package com.lmx.persistence.service;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.lmx.common.constants.CommonConstants;
import com.lmx.common.constants.LeaveStatus;
import com.lmx.common.context.ActionContextHolder;
import com.lmx.common.util.CommonUtil;
import com.lmx.common.util.PropertiesFileUtil;
import com.lmx.repoDomain.exception.BusinessException;
import com.lmx.repoDomain.tmodel.Conf;
import com.lmx.repoDomain.tmodel.Customer;
import com.lmx.repoDomain.tmodel.CustomerDrug;
import com.lmx.repoDomain.tmodel.CustomerDrugProject;
import com.lmx.repoDomain.tmodel.CustomerDrugProjectExe;
import com.lmx.repoDomain.tmodel.CustomerDrugProjectItem;
import com.lmx.repoDomain.tmodel.CustomerDrugRecord;
import com.lmx.repoDomain.tmodel.CustomerFoodPlan;
import com.lmx.repoDomain.tmodel.CustomerLeave;
import com.lmx.repoDomain.tmodel.CustomerNursingPlan;
import com.lmx.repoDomain.tmodel.CustomerNursingPlanModel;
import com.lmx.repoDomain.tmodel.CustomerServiceBill;
import com.lmx.repoDomain.tmodel.CustomerServiceItem;
import com.lmx.repoDomain.tmodel.Dicttype;
import com.lmx.repoDomain.tmodel.DicttypeTenant;
import com.lmx.repoDomain.tmodel.Employee;
import com.lmx.repoDomain.tmodel.EvaluateAnswer;
import com.lmx.repoDomain.tmodel.EvaluateBatch;
import com.lmx.repoDomain.tmodel.EvaluateExamerAnswer;
import com.lmx.repoDomain.tmodel.EvaluateModel;
import com.lmx.repoDomain.tmodel.EvaluateQuestion;
import com.lmx.repoDomain.tmodel.EvaluateResult;
import com.lmx.repoDomain.tmodel.EvaluateScoreScope;
import com.lmx.repoDomain.tmodel.HbeaconWarning;
import com.lmx.repoDomain.tmodel.NurseGroup;
import com.lmx.repoDomain.tmodel.NurseMerch;
import com.lmx.repoDomain.tmodel.NursingLevel;
import com.lmx.repoDomain.tmodel.NursingPlanDetail;
import com.lmx.repoDomain.tmodel.NursingPlanExecute;
import com.lmx.repoDomain.tmodel.NursingPlanServiceItem;
import com.lmx.repoDomain.tmodel.NursingProject;
import com.lmx.repoDomain.tmodel.NursingProjectServiceItem;
import com.lmx.repoDomain.tmodel.RecordViolation;
import com.lmx.repoDomain.tmodel.Role;
import com.lmx.repoDomain.tmodel.ServiceFinishLevel;
import com.lmx.repoDomain.tmodel.ServiceMerch;
import com.lmx.repoDomain.tmodel.ServicesExe;
import com.lmx.repoDomain.tmodel.SpecService;
import com.lmx.repoDomain.tmodel.WorkTimeSetting;
import com.lmx.repoDomain.tmodel.business.User;

/**
 *
 *
 * @author huibati
 * @version 1.00
 */
@Service
@Scope("prototype")
public class NursingService<T> {

	private Log logger = LogFactory.getLog(this.getClass());

	private Properties properties = PropertiesFileUtil.getApplicationProperties();

	@PersistenceContext
	private EntityManager em;

	@Autowired
	protected GenericService dslJpaService;

	@Autowired
	protected UserService userService;

	@Autowired
	protected CommonService commonService;

	@Autowired
	protected WeiXinService weiXinService;

	@Autowired
	protected StatService statService;

	public void addPlanItem(NursingPlanServiceItem planItem) {
		dslJpaService.setEntityClass(NursingPlanServiceItem.class);
		dslJpaService.create(planItem);
	}

	/**
	 * delete NursingPlanServiceItem
	 */
	@Transactional
	public void deleteNursingPlanServiceItem(Long planId) {
		if (planId != null) {
			StringBuilder query = new StringBuilder(
					"delete from NursingPlanServiceItem rp where rp.plan.id = ?1");
			this.em.createQuery(query.toString()).setParameter(1, planId).executeUpdate();
		}
	}

	/**
	 * update NursingPlanServiceItem
	 */
	@Transactional
	public void updateNursingPlanServiceItemStatus(Long planId) {
		if (planId != null) {
			StringBuilder query = new StringBuilder(
					"update  NursingPlanServiceItem rp set rp.delStatus=1 where rp.plan.id = ?1 and rp.delStatus=?2 ");
			this.em.createQuery(query.toString()).setParameter(1, planId)
					.setParameter(2, (short) 0).executeUpdate();
		}
	}

	/**
	 * 获取护工单前所需完成的planitem 弃用
	 */
	public Iterable<NursingPlanServiceItem> getStaffPlanItem(long userId) {
		Role role = userService.getRoleByUserId(userId);
		Date date = new Date();
		int weekTab = -1;
		int startTimeTab = -1;
		// weekTab = CommonUtil.getWeekOfDate(date);
		if (weekTab == 0) {
			weekTab = 7;
		}
		SimpleDateFormat sim = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String dateStr = sim.format(date);
		int hour = Integer.parseInt(dateStr.substring(11, 13));
		int min = Integer.parseInt(dateStr.substring(14, 16));
		if (min < 30) {
			startTimeTab = hour * 2;
		} else {
			startTimeTab = hour * 2 + 1;
		}
		// huibati 获取 user所对应 employee 在获取 employee所对应customer
		List<NursingPlanServiceItem> dataList = new ArrayList<NursingPlanServiceItem>();

		List<Customer> customerList = this.em
				.createQuery(
				// "select c.customer from EmployeeCustomer c where c.employee
				// in (select u.employee from User u where u.id = ?1 ) "
						"select c from Customer c where c.bed in ( select b from Bed b where b.delStatus != ?1 "
								+ "and b in( select n.bed from BedNurseGroup n where n.delStatus != ?1 "
								+ "and n.group in( select c.group from EmployeeNursingGroup c where c.employee in (select u.employee from User u where u.id = ?2 )) "
								+ "))").setParameter(1, (short) 1).setParameter(2, userId)
				.getResultList();
		List<NursingPlanServiceItem> itemList = new ArrayList<NursingPlanServiceItem>();
		if (customerList.size() > 0) {
			// 获取当前护工所护理老人对应的 NursingPlanServiceItem
			String query = "select c from NursingPlanServiceItem c JOIN FETCH c.plan plan "
					+ "where c.delStatus != ?1  and c.weekTab=:weekTab and plan.customer in(:olds) "
					+ "and ( "
					+ "(plan.planEndTime is not null and plan.planStartTime <=:nowTime and plan.planEndTime>=:nowTime )"
					+ " or ( plan.planEndTime = null and plan.planStartTime <=:nowTime )" + " )";//
			itemList = this.em.createQuery(query).setParameter(1, (short) 1)
					.setParameter("weekTab", weekTab).setParameter("olds", customerList)
					.setParameter("nowTime", CommonUtil.getCurrTimes()).getResultList();
		}
		for (NursingPlanServiceItem item : itemList) {
			if (item != null) {
				if (item.getItem().getItem().getRoleType() != null) {
					Long t1 = item.getItem().getItem().getRoleType().getId();
					Long t2 = role.getRoleType().getId();
					if (item.getItem().getItem().getRoleType().getId().longValue() == role
							.getRoleType().getId().longValue()) {// item角色类型与当前staff
																	// 所属角色类型一致
						dataList.add(item);
					}
				}
			}
		}
		return dataList;
	}

	/**
	 * 获取护工单前所需完成的projectitem 不定时任务
	 */
	public Iterable<NursingProjectServiceItem> getStaffProjectItem(long userId) {
		// Role role = userService.getRoleByUserId(userId);//获取user对应角色
		List<NursingProjectServiceItem> itemList = new ArrayList<NursingProjectServiceItem>();
		// huibati 获取 user所对应 employee 在获取 employee所对应customer
		StringBuilder queryCustomer = new StringBuilder(
				"select c from Customer c where c.delStatus != 1 and c.customerStatus is not null and ( c.customerStatus.typecode=?3 or c.customerStatus.typecode=?4 or c.customerStatus.typecode=?5 ) "
						+ " and c.bed in ( select b from Bed b where b.delStatus != ?1 "
						+ " and b in( select n.bed from BedNurseGroup n where n.delStatus != ?1 "
						+ " and n.group in( select c.group from EmployeeNursingGroup c where c.delStatus != 1 and c.employee in (select u.employee from User u where u.id = ?2 )) "
						+ "))");
		List<Customer> customerList = this.em.createQuery(queryCustomer.toString())
				.setParameter(1, (short) 1).setParameter(2, userId)
				.setParameter(3, "customerStatusIn").setParameter(4, "customerStatusTry")
				.setParameter(5, "customerStatusTryWaitIn").getResultList();
		if (customerList.size() > 0) {
			// 获取当前护工所护理老人对应的 NursingProjectServiceItem 通过角色类型进行过滤
			StringBuilder queryItem = new StringBuilder(
					"select item from NursingProjectServiceItem item JOIN FETCH item.project project "
							+ "where item.delStatus != ?1 and project.customer in(:olds) ");
			List<NursingProjectServiceItem> list = this.em.createQuery(queryItem.toString())
					.setParameter(1, (short) 1).setParameter("olds", customerList).getResultList();
			for (int i = 0; i < list.size(); i++) {
				NursingProjectServiceItem item = list.get(i);
				if (item == null) {
					logger.debug("null-----------------------------------------------");
				} else {
					StringBuilder queryRelation = new StringBuilder(
							"select c.serviceType.typecode from PositionServiceType c where c.position in (select u.employee.position from User u where u.id = ?1 )  ");
					List<String> serviceTypeList = this.em.createQuery(queryRelation.toString())
							.setParameter(1, userId).getResultList();
					if (serviceTypeList.size() > 0) {
						if ("countTypeByFrequency".equals(item.getItem().getCountType()
								.getTypecode())) {
							// 修改为item所对应的Servicetype与当前user所对应的Employee的岗位所对应的Servicetype一致
							if (item.getItem().getServiceType() != null) {
								if (serviceTypeList.contains(item.getItem().getServiceType()
										.getTypecode())) {
									itemList.add(item);
								}
							}
						} // end count
					}
				}
			}
		}
		return itemList;
	}

	/**
	 * 扫码 直接获取 customer projectitem
	 */
	public Iterable<NursingProjectServiceItem> getCustomerProjectItem(long customerId) {
		List<NursingProjectServiceItem> itemList = new ArrayList<NursingProjectServiceItem>();
		if (ActionContextHolder.getContext().getUser() != null
				&& ActionContextHolder.getContext().getUser().getId() != null) {
			long userId = ActionContextHolder.getContext().getUser().getId();
			List<Long> customerList = new ArrayList<>();
			customerList.add(customerId);
			if (customerList.size() > 0) {
				// 获取老人对应的 NursingProjectServiceItem 通过角色类型进行过滤
				StringBuilder queryItem = new StringBuilder(
						"select item from NursingProjectServiceItem item JOIN FETCH item.project project "
								+ "where item.delStatus != ?1 and project.customer.id in(:olds) ");
				List<NursingProjectServiceItem> list = this.em.createQuery(queryItem.toString())
						.setParameter(1, (short) 1).setParameter("olds", customerList)
						.getResultList();
				for (int i = 0; i < list.size(); i++) {
					NursingProjectServiceItem item = list.get(i);
					if (item == null) {
						logger.debug("null-----------------------------------------------");
					} else {
						StringBuilder queryRelation = new StringBuilder(
								"select c.serviceType.typecode from PositionServiceType c where c.position in (select u.employee.position from User u where u.id = ?1 )  ");
						List<String> serviceTypeList = this.em
								.createQuery(queryRelation.toString()).setParameter(1, userId)
								.getResultList();
						if (serviceTypeList.size() > 0) {
							if ("countTypeByFrequency".equals(item.getItem().getCountType()
									.getTypecode())) {
								// 修改为item所对应的Servicetype与当前user所对应的Employee的岗位所对应的Servicetype一致
								if (item.getItem().getServiceType() != null) {
									if (serviceTypeList.contains(item.getItem().getServiceType()
											.getTypecode())) {
										itemList.add(item);
									}
								}
							} // end count
						} // end serviceTypeList
					}
				}
			}
		}
		return itemList;
	}

	/**
	 * 获取nursingproject
	 */
	public NursingProject getProjectByCustomer(Customer customer) {
		Long id = customer.getId();
		List resultList = this.em
				.createQuery(
						"select c from NursingProject c where c.delStatus!=1 and c.customer.id = ?1 ")
				.setParameter(1, id).getResultList();
		NursingProject u = null;
		if (resultList.size() > 0) {
			u = (NursingProject) resultList.get(0);
		}
		return u;
	}

	/**
	 * 获取没有分组的护工
	 */
	public Iterable<Employee> getEmployeeListFilterGroup() {
		StringBuilder queryStaff = new StringBuilder(
				"select c from Employee c where c.delStatus != ?1 and c.tenant.id=?3 and c not in ( select p.employee from EmployeeNursingGroup p where p.delStatus != ?2 and  p.tenant.id=?3) ");
		List dataList = this.em.createQuery(queryStaff.toString()).setParameter(1, (short) 1)
				.setParameter(2, (short) 1)
				.setParameter(3, ActionContextHolder.getContext().getTenantId()).getResultList();
		return dataList;
	}

	/**
	 * 获取nursinglevel
	 */
	public NursingLevel getNursingLevelByResult(EvaluateResult result) {
		Integer score = Integer.parseInt(result.getScore());
		StringBuilder queryLevel = new StringBuilder(
				"select c from NursingLevel c where c.delStatus != ?1 and c.lowScore <= ?2 and c.highScore >=?2 and c.tenant.id=?3 ");
		List resultList = this.em.createQuery(queryLevel.toString()).setParameter(1, (short) 1)
				.setParameter(2, score)
				.setParameter(3, ActionContextHolder.getContext().getTenantId()).getResultList();
		NursingLevel u = null;
		if (resultList.size() > 0) {
			u = (NursingLevel) resultList.get(0);
		}
		return u;
	}

	/**
	 * 获取nurseGroup
	 */
	public NurseGroup getNurseGroupById(Long id) {
		StringBuilder query = new StringBuilder(
				"select c from NurseGroup c where c.id = ?1 and c.delStatus != ?2");
		List resultList = this.em.createQuery(query.toString()).setParameter(1, id)
				.setParameter(2, (short) 1).getResultList();
		NurseGroup u = null;
		if (resultList.size() > 0) {
			u = (NurseGroup) resultList.get(0);
		}
		return u;
	}

	/**
	 * 获取nurseGroup
	 */
	public NurseGroup getNurseGroupByName(String name) {
		StringBuilder query = new StringBuilder(
				"select c from NurseGroup c where c.name = ?1 and c.delStatus != ?2 and c.tenant.id=?3");
		List resultList = this.em.createQuery(query.toString()).setParameter(1, name)
				.setParameter(2, (short) 1)
				.setParameter(3, ActionContextHolder.getContext().getTenantId()).getResultList();
		NurseGroup u = null;
		if (resultList.size() > 0) {
			u = (NurseGroup) resultList.get(0);
		}
		return u;
	}

	@Transactional
	public void deleteNursrGroup(Long id) {
		if (id != null) {
			StringBuilder queryBed = new StringBuilder(
					"delete from BedNurseGroup rp where rp.group.id = ?1");
			this.em.createQuery(queryBed.toString()).setParameter(1, id).executeUpdate();

			StringBuilder queryStaff = new StringBuilder(
					"delete from EmployeeNursingGroup rp where rp.group.id = ?1");
			this.em.createQuery(queryStaff.toString()).setParameter(1, id).executeUpdate();
		}
	}

	/**
	 * 获取
	 */
	public List<WorkTimeSetting> getWorkTimeSettingByName(String name) {
		StringBuilder query = new StringBuilder(
				"select c from WorkTimeSetting c where c.name = ?1 and c.delStatus != ?2 and c.tenant.id=?3");
		List resultList = this.em.createQuery(query.toString()).setParameter(1, name)
				.setParameter(2, (short) 1)
				.setParameter(3, ActionContextHolder.getContext().getTenantId()).getResultList();

		return resultList;
	}

	/**
	 * 获取
	 */
	public WorkTimeSetting getWorkTimeSettingById(Long id) {
		StringBuilder query = new StringBuilder(
				"select c from WorkTimeSetting c where c.id = ?1 and c.delStatus != ?2 ");
		List resultList = this.em.createQuery(query.toString()).setParameter(1, id)
				.setParameter(2, (short) 1).getResultList();
		WorkTimeSetting u = null;
		if (resultList.size() > 0) {
			u = (WorkTimeSetting) resultList.get(0);
		}
		return u;
	}

	/**
	 * 获取NursingLevel
	 */
	public NursingLevel getNursingLevelById(Long id) {
		StringBuilder query = new StringBuilder(
				"select c from NursingLevel c where c.id = ?1 and c.delStatus != ?2");
		List resultList = this.em.createQuery(query.toString()).setParameter(1, id)
				.setParameter(2, (short) 1).getResultList();
		NursingLevel u = null;
		if (resultList.size() > 0) {
			u = (NursingLevel) resultList.get(0);
		}
		return u;
	}

	/**
	 * 获取NursingLevel
	 */
	public NursingLevel getNursingLevelByName(String name) {
		StringBuilder query = new StringBuilder(
				"select c from NursingLevel c where c.name = ?1 and c.delStatus != ?2 and c.tenant.id=?3");
		List resultList = this.em.createQuery(query.toString()).setParameter(1, name)
				.setParameter(2, (short) 1)
				.setParameter(3, ActionContextHolder.getContext().getTenantId()).getResultList();
		NursingLevel u = null;
		if (resultList.size() > 0) {
			u = (NursingLevel) resultList.get(0);
		}
		return u;
	}

	/**
	 * 获取NurseGroup bed处于试住 入住
	 */
	public List<NurseGroup> getNurseGroupByCustomerName(String name) {
		StringBuilder queryBed = new StringBuilder(
				"select c.bed from Customer c where  c.delStatus != ?1 and c.tenant.id=?2 "
						+ "and c.name like '%" + name + "%' "
						+ "and (c.bed.status.typecode=?4 or c.bed.status.typecode=?3 ) ");
		List bedList = this.em.createQuery(queryBed.toString()).setParameter(1, (short) 1)
				.setParameter(2, ActionContextHolder.getContext().getTenantId())
				.setParameter(4, CommonConstants.DICTTYPE.BED_STATUS_3.label())
				.setParameter(3, CommonConstants.DICTTYPE.BED_STATUS_2.label()).getResultList();
		List dataList = new ArrayList<>();
		if (bedList != null && bedList.size() > 0) {
			StringBuilder queryGroup = new StringBuilder(
					"select distinct c.group from BedNurseGroup c where c.delStatus != ?1 and c.tenant.id=?2 and c.group.delStatus != ?1 and c.bed in (:beds) ");
			dataList = this.em.createQuery(queryGroup.toString()).setParameter(1, (short) 1)
					.setParameter(2, ActionContextHolder.getContext().getTenantId())
					.setParameter("beds", bedList).getResultList();
		}
		return dataList;
	}

	/**
	 * 获取NurseGroup
	 */
	public List<NurseGroup> getNurseGroupByStaffName(String name) {
		StringBuilder queryStaff = new StringBuilder(
				"select c from Employee c where c.delStatus != ?1 and c.tenant.id=?2 and c.name like '%"
						+ name + "%' ");
		List staffList = this.em.createQuery(queryStaff.toString()).setParameter(1, (short) 1)
				.setParameter(2, ActionContextHolder.getContext().getTenantId()).getResultList();
		List dataList = new ArrayList<>();
		if (staffList != null && staffList.size() > 0) {
			StringBuilder queryGroup = new StringBuilder(
					"select distinct c.group from EmployeeNursingGroup c where c.delStatus != ?1 and c.tenant.id=?2 and c.group.delStatus != ?1 and c.employee in (:staffs) ");
			dataList = this.em.createQuery(queryGroup.toString()).setParameter(1, (short) 1)
					.setParameter(2, ActionContextHolder.getContext().getTenantId())
					.setParameter("staffs", staffList).getResultList();
		}
		return dataList;
	}

	/**
	 * 获取NurseGroup
	 */
	public List<NurseGroup> getNurseGroupByCustomer(Customer customer) {
		StringBuilder queryBed = new StringBuilder(" select c.bed from Customer c where c.id = ?1 ");
		List bedList = this.em.createQuery(queryBed.toString()).setParameter(1, customer.getId())
				.getResultList();
		List dataList = new ArrayList<>();
		if (bedList != null && bedList.size() > 0) {
			StringBuilder queryGroup = new StringBuilder(
					"select distinct c.group from BedNurseGroup c where c.delStatus != ?1 and c.tenant.id=?2 and c.group.delStatus != ?1 and c.bed in (:beds) ");
			dataList = this.em.createQuery(queryGroup.toString()).setParameter(1, (short) 1)
					.setParameter(2, ActionContextHolder.getContext().getTenantId())
					.setParameter("beds", bedList).getResultList();
		}
		return dataList;
	}

	/**
	 * 摘取数据
	 */

	public List getCustomersFromCustomerNursingPlan(CustomerNursingPlan record) {
		// 删除原有数据
		List customers = new ArrayList<>();
		if (record.getDetails() != null && record.getDetails().size() > 0) {
			for (NursingPlanDetail detail : record.getDetails()) {
				if (customers.contains(detail.getCustomer())) {

				} else {
					customers.add(detail.getCustomer());
				}
			}
		}
		return customers;
	}

	/**
	 * 摘取数据
	 */

	public Map getCustomerPlanDetailDatas(CustomerNursingPlan record) {
		// 删除原有数据
		Map<Object, List> detailData = new HashMap<>();
		if (record.getDetails() != null && record.getDetails().size() > 0) {
			for (NursingPlanDetail detail : record.getDetails()) {
				if (detailData.containsKey(detail.getCustomer())) {

				} else {
					detailData.put(detail.getCustomer(), new ArrayList<>());
				}
				detailData.get(detail.getCustomer()).add(detail);
			}
		}
		return detailData;
	}

	/**
	 * 删除日护理计划 （日计划或者周计划）
	 */
	@Transactional
	public void deletePlanDayDetailByRecord(CustomerNursingPlan record) {
		// 删除原有数据
		List customers = new ArrayList<>();
		if (record.getCustomers() != null && !"".equals(record.getCustomers())) {
			String[] ids = record.getCustomers().split(",");
			for (String id : ids) {
				if (!"".equals(id)) {
					customers.add(Long.valueOf(id));
				}
			}
		}
		Integer weekTab = record.getWeekTab();
		String periodType = "";
		if ("month".equals(record.getItemType())) {
			periodType = "periodMonth";
		}
		if ("week".equals(record.getItemType())) {
			periodType = "periodWeek";
		}
		if ("day".equals(record.getItemType())) {
			periodType = "periodDay";
		}
		if (customers != null && customers.size() > 0) {
			List<NursingPlanDetail> dataList = new ArrayList<>();
			StringBuilder queryDetail = new StringBuilder(
					"select  c from  NursingPlanDetail c where c.customer is not null  "
							+ " and c.customer.id in (:olds) "
							+ " and ( c.yearTab=?1 and c.weekIndex=?2 and c.weekTab=?3 "
							+ " and c.item.item.period.typecode=?4)");
			dataList = this.em.createQuery(queryDetail.toString())
					.setParameter(1, record.getYearTab()).setParameter(2, record.getWeekIndex())
					.setParameter(3, weekTab).setParameter(4, periodType)
					.setParameter("olds", customers).getResultList();
			if (dataList.size() > 0) {
				StringBuilder query = new StringBuilder(
						" delete from  NursingPlanDetail c where c in (:dataList) ");
				this.em.createQuery(query.toString()).setParameter("dataList", dataList)
						.executeUpdate();
			}
		}
	}

	/**
	 * 删除护理计划 记录当天所有计划
	 */
	@Transactional
	public void deletePlanDetailByRecord(CustomerNursingPlan record) {
		// 删除原有数据
		// List customers = getCustomersFromCustomerNursingPlan(record);
		List customers = new ArrayList<>();
		if (record.getCustomers() != null && !"".equals(record.getCustomers())) {
			String[] ids = record.getCustomers().split(",");
			for (String id : ids) {
				if (!"".equals(id)) {
					customers.add(Long.valueOf(id));
				}
			}
		}
		Date now = new Date();
		Integer weekTab = CommonUtil.getWeek(now);
		if (weekTab == 0)
			weekTab = 7;
		int weekIndex = CommonUtil.getWeekIndexFromSun(now);
		if (customers != null && customers.size() > 0) {
			StringBuilder query = new StringBuilder(
					"delete from  NursingPlanDetail c where c.customer is not null "
							+ "and c.customer.id in (:olds) ");
			// 验证是所传周是不是当前周 是的话今天以前几天数据不删
			if (weekIndex == record.getWeekIndex()) {// 当前周
				query.append(" and ( c.yearTab=?1 and c.weekIndex=?2 and c.weekTab>?3) ");
				this.em.createQuery(query.toString()).setParameter(1, record.getYearTab())
						.setParameter(2, record.getWeekIndex()).setParameter(3, weekTab)
						.setParameter("olds", customers).executeUpdate();
			} else {// 以后几周
				query.append(" and ( c.yearTab=?1 and c.weekIndex=?2 ) ");
				this.em.createQuery(query.toString()).setParameter(1, record.getYearTab())
						.setParameter(2, record.getWeekIndex()).setParameter("olds", customers)
						.executeUpdate();
			}
		}
	}

	/**
	 * 删除护理计划 未来几周
	 */
	@Transactional
	public void deletePlanDetailNextWeeks(CustomerNursingPlan record, int weekNum) {
		// 删除原有数据
		// List customers = getCustomersFromCustomerNursingPlan(record);
		List customers = new ArrayList<>();
		if (record.getCustomers() != null && !"".equals(record.getCustomers())) {
			String[] ids = record.getCustomers().split(",");
			for (String id : ids) {
				if (!"".equals(id)) {
					customers.add(Long.valueOf(id));
				}
			}
		}
		if (customers != null && customers.size() > 0) {
			Map<Integer, String> dateTab = new HashMap<>();
			dateTab.put(0, record.getYearTab() + "," + record.getWeekIndex());
			for (Integer i = 0; i < weekNum + 1; i++) {
				if (i > 0) {
					Integer yearTab = Integer.valueOf(dateTab.get(i - 1).split(",")[0]);
					Integer weekIndex = Integer.valueOf(dateTab.get(i - 1).split(",")[1]) + 1;
					if (weekIndex > 52) {
						weekIndex = 1;
						yearTab++;
					}
					dateTab.put(i, yearTab + "," + weekIndex);
				}
			}
			StringBuilder query = new StringBuilder(
					"delete from  NursingPlanDetail c where c.customer is not null "
							+ "and c.customer.id in (:olds) " + "and " + " ("
							+ " ( c.yearTab=?1 and c.weekIndex=?2 ) or"
							+ " ( c.yearTab=?3 and c.weekIndex=?4 ) or"
							+ " ( c.yearTab=?5 and c.weekIndex=?6 ) or"
							+ " ( c.yearTab=?7 and c.weekIndex=?8 ) " + " )");
			Integer t = Integer.valueOf(dateTab.get(1).split(",")[0]);
			this.em.createQuery(query.toString()).setParameter(1, record.getYearTab())
					.setParameter(2, record.getWeekIndex()).setParameter(3, t)
					.setParameter(4, Integer.valueOf(dateTab.get(1).split(",")[1]))
					.setParameter(5, Integer.valueOf(dateTab.get(2).split(",")[0]))
					.setParameter(6, Integer.valueOf(dateTab.get(2).split(",")[1]))
					.setParameter(7, Integer.valueOf(dateTab.get(3).split(",")[0]))
					.setParameter(8, Integer.valueOf(dateTab.get(3).split(",")[1]))
					.setParameter("olds", customers).executeUpdate();
		}
	}

	/**
	 * 删除未来四周护理计划
	 */
	@Transactional
	public void deletePlanDetailNextWeeksByCustomer(Customer customer, int weekNum) {
		// 删除原有数据
		if (weekNum > 0 && customer != null) {
			Map<Integer, String> dateTab = new HashMap<>();
			int yearNow = (new Date().getYear() + 1900);
			int weekIndexNow = CommonUtil.getWeekIndexFromSun(new Date());// 以周末为第一天当前是第几周
			if (weekIndexNow + 1 > 52) {
				dateTab.put(0, (yearNow + 1) + "," + 1);
			} else {
				dateTab.put(0, yearNow + "," + (weekIndexNow + 1));
			}
			for (Integer i = 0; i < weekNum; i++) {
				if (i > 0) {
					Integer yearTab = Integer.valueOf(dateTab.get(i - 1).split(",")[0]);
					Integer weekIndex = Integer.valueOf(dateTab.get(i - 1).split(",")[1]) + 1;
					if (weekIndex > 52) {
						weekIndex = 1;
						yearTab++;
					}
					dateTab.put(i, yearTab + "," + weekIndex);
				}
			}
			StringBuilder query = new StringBuilder(
					"delete from  NursingPlanDetail c where c.customer is not null "
							+ "and c.customer.id =?9  " + "and ("
							+ " ( c.yearTab=?1 and c.weekIndex=?2 ) or "
							+ " ( c.yearTab=?3 and c.weekIndex=?4 ) or "
							+ " ( c.yearTab=?5 and c.weekIndex=?6 ) or "
							+ " ( c.yearTab=?7 and c.weekIndex=?8 ) " + "    )");
			this.em.createQuery(query.toString())
					.setParameter(1, Integer.valueOf(dateTab.get(0).split(",")[0]))
					.setParameter(2, Integer.valueOf(dateTab.get(0).split(",")[1]))
					.setParameter(3, Integer.valueOf(dateTab.get(1).split(",")[0]))
					.setParameter(4, Integer.valueOf(dateTab.get(1).split(",")[1]))
					.setParameter(5, Integer.valueOf(dateTab.get(2).split(",")[0]))
					.setParameter(6, Integer.valueOf(dateTab.get(2).split(",")[1]))
					.setParameter(7, Integer.valueOf(dateTab.get(3).split(",")[0]))
					.setParameter(8, Integer.valueOf(dateTab.get(3).split(",")[1]))
					.setParameter(9, customer.getId()).executeUpdate();
		}
	}

	/**
	 * 删除护理计划模版
	 */
	@Transactional
	public void deletePlanItemByCustomerId(Long customerId) {
		Date now = new Date();
		int yearNow = (now.getYear() + 1900);
		int weekIndexNow = CommonUtil.getWeekIndexFromSun(now);
		int weekTab = CommonUtil.getWeek(now);
		int deleteNowFlag = checkPlanDetailNowRelations(customerId, yearNow, weekIndexNow, weekTab);
		// 删除今天以后当周的护理计划
		StringBuilder queryNow = new StringBuilder(
				"delete from  NursingPlanDetail c where c.customer is not null "
						+ " and c.customer.id =?1 and c.yearTab=?2 and ( c.weekIndex >?3  or ( c.weekIndex =?3 ");
		if (deleteNowFlag == 0) {
			queryNow.append(" and c.weekTab >=?4 ))");
		} else {
			queryNow.append(" and c.weekTab >?4 ))");
		}
		this.em.createQuery(queryNow.toString()).setParameter(1, customerId)
				.setParameter(2, yearNow).setParameter(3, weekIndexNow).setParameter(4, weekTab)
				.executeUpdate();
		// 删除原有模版
		StringBuilder query = new StringBuilder(
				"delete from  NursingPlanServiceItem c  where c.customer is not null and c.customer.id= ?1 ");
		this.em.createQuery(query.toString()).setParameter(1, customerId).executeUpdate();
	}

	/**
	 * 删除护理计划模版 弃用
	 */
	@Transactional
	public void deletePlanItem(CustomerNursingPlan record) {
		// 删除原有数据
		List customers = getCustomersFromCustomerNursingPlan(record);
		if (record.getDetails() != null && record.getDetails().size() > 0 && customers.size() > 0) {
			StringBuilder query = new StringBuilder(
					"delete from  NursingPlanServiceItem c  where c.customer is not null and c.customer in (:olds)");
			this.em.createQuery(query.toString()).setParameter("olds", customers).executeUpdate();
		}
	}

	/**
	 * 产生护理计划模版
	 */
	public void createPlanItem(CustomerNursingPlan record) {
		List dataList = new ArrayList<>();
		if (record.getDetails() != null && record.getDetails().size() != 0) {
			for (NursingPlanDetail detail : record.getDetails()) {
				if (detail != null && detail.getDelStatus() != null && detail.getDelStatus() != 1) {
					NursingPlanServiceItem item = new NursingPlanServiceItem();
					item.setCustomer(detail.getCustomer());
					item.setDelStatus((short) 0);
					item.setItem(detail.getItem());
					item.setWeekTab(detail.getWeekTab());
					item.setMonthTab(detail.getMonthTab());
					item.setStartTimeTab(detail.getStartTimeTab());
					item.setTenant(detail.getCustomer().getTenant());
					dataList.add(item);
				}
			}
			if (dataList.size() > 0) {
				commonService.batchInsert(dataList);// 产生模版
			}
		}
	}

	/**
	 * 当天护理计划是否执行过
	 */
	public int checkPlanDetailNowRelations(Long customerId, int yearTab, int weekIndex, int weekTab) {
		StringBuilder queryNow = new StringBuilder(
				"select c from  NursingPlanExecute c where c.detail is not null and c.detail.customer is not null "
						+ " and c.detail.customer.id =?1 and c.detail.yearTab=?2 and c.detail.weekIndex =?3 and c.detail.weekTab =?4 ");
		List dataList = this.em.createQuery(queryNow.toString()).setParameter(1, customerId)
				.setParameter(2, yearTab).setParameter(3, weekIndex).setParameter(4, weekTab)
				.getResultList();
		if (dataList == null || dataList.size() == 0) {
			return 0;
		} else
			return dataList.size();
	}

	/**
	 * 复制当天护理计划
	 */
	public void copyPlanToday(CustomerNursingPlan record) {
		logger.debug("start copyPlanToday " + CommonUtil.getCurrTimeForString());
		List dataList = new ArrayList<>();
		Date dateTemp = new Date();
		if (record.getDetails() != null && record.getDetails().size() != 0) {
			for (NursingPlanDetail detail : record.getDetails()) {
				if (detail != null && detail.getDelStatus() != null && detail.getDelStatus() != 1) {
					int weekIndex = CommonUtil.getWeekIndexFromSun(dateTemp);
					int monthIndex = dateTemp.getMonth();
					int monthTab = dateTemp.getDate();
					int year = dateTemp.getYear() + 1900;// 年 周 序号

					if (record.getYearTab() == year && record.getMonthIndex() == monthIndex
							&& record.getMonthTab() == monthTab) {
						NursingPlanDetail data = new NursingPlanDetail();
						data.setCreateDateTime(CommonUtil.getCurrTimes());
						data.setCustomer(detail.getCustomer());
						data.setItem(detail.getItem());
						data.setDelStatus((short) 0);
						data.setStartTimeTab(detail.getStartTimeTab());
						data.setTenant(detail.getCustomer().getTenant());
						data.setWeekTab(detail.getWeekTab());// 周几
						data.setWeekIndex(weekIndex);// 第几周
						data.setMonthIndex(monthIndex);
						data.setMonthTab(monthTab);
						data.setYearTab(year);
						dataList.add(data);
					}
				}
			}
			if (dataList.size() > 0) {
				commonService.batchInsert(dataList);
			}
		}
	}

	/**
	 * 按照星期 复制护理计划
	 */
	public void copyPlanToNextWeeks(CustomerNursingPlan record, int weeksNum) { // record数据是下周数据
		logger.debug("start copy CustomerNursingPlan " + CommonUtil.getCurrTimeForString()
				+ " weekNum " + weeksNum);
		List dataList = new ArrayList<>();
		Date dateTemp = null;
		if (record.getDetails() != null && record.getDetails().size() != 0) {
			for (NursingPlanDetail detail : record.getDetails()) {
				if (detail != null && detail.getDelStatus() != null && detail.getDelStatus() != 1) {
					for (int i = 0; i < weeksNum + 2; i++) {
						if (i == 0) {
							dateTemp = new Date();// 本周 已经存在 i=1是下周 2 3 4为后三周
						}
						int weekIndex = CommonUtil.getWeekIndexFromSun(dateTemp);
						int year = dateTemp.getYear() + 1900;// 产生下三周的 年 周 序号
						dateTemp = CommonUtil.getNextSaturday(dateTemp, 1);// 下周6的时间
						if (i > 1) {
							NursingPlanDetail data = new NursingPlanDetail();
							data.setCreateDateTime(CommonUtil.getCurrTimes());
							data.setCustomer(detail.getCustomer());
							data.setItem(detail.getItem());
							data.setDelStatus((short) 0);
							data.setStartTimeTab(detail.getStartTimeTab());
							data.setTenant(detail.getCustomer().getTenant());
							data.setWeekTab(detail.getWeekTab());// 周几
							data.setWeekIndex(weekIndex);// 第几周
							data.setYearTab(year);
							dataList.add(data);
						}
					}
				}
			}
			if (dataList.size() > 0) {
				commonService.batchInsert(dataList); // 复制到后三周
			}
		}
	}

	/**
	 * 根据CustomerNursingPlanModel复制产生当日护理计划
	 */
	public void copyPlanToToday(CustomerNursingPlanModel model, Long id) {
		logger.info("start copy CustomerNursingPlanModel PlanToToday "
				+ CommonUtil.getCurrTimeForString() + " customer_id " + id);
		List<NursingPlanDetail> dataList = new ArrayList<>();
		Date dateTemp = new Date();
		int weekIndex = CommonUtil.getWeekIndexFromSun(dateTemp);
		int year = dateTemp.getYear() + 1900;// 产生 年 周 序号
		int weekTab = CommonUtil.getWeek(dateTemp);
		int monthTab = dateTemp.getDate();
		int monthIndex = dateTemp.getMonth();

		// 验证当天护理计划是否被执行过
		int copyNowFlag = checkPlanDetailNowRelations(id, year, weekIndex, weekTab);
		if (copyNowFlag > 0) {
			throw new BusinessException(null, CommonConstants.ERROR_CODE.REPEAT_ERROR.label(), null);
		}

		if (model.getItems() != null && model.getItems().size() != 0) {
			for (NursingPlanServiceItem item : model.getItems()) {
				if (item != null && item.getDelStatus() != null && item.getDelStatus() != 1) {
					NursingPlanDetail data = new NursingPlanDetail();
					data.setCreateDateTime(CommonUtil.getCurrTimes());
					data.setCustomer(item.getCustomer());
					data.setItem(item.getItem());
					data.setDelStatus((short) 0);
					data.setStartTimeTab(item.getStartTimeTab());
					data.setTenant(item.getTenant());
					data.setWeekTab(weekTab);// 周几
					data.setWeekIndex(weekIndex);// 第几周
					data.setMonthIndex(monthIndex);
					data.setMonthTab(monthTab);
					data.setYearTab(year);

					if (item.getWeekTab() != null && item.getWeekTab() == weekTab) {// 周计划
						dataList.add(data);
					} else if (item.getMonthTab() != null && item.getMonthTab() == monthTab) { // 月计划
						dataList.add(data);
					} else if (item.getWeekTab() == null && item.getMonthTab() == null) { // 日计划每天都有
						dataList.add(data);
					}
				}
			}
			if (dataList.size() > 0) {
				logger.info(" copyPlanToToday customer_id " + id + " size === " + dataList.size());
				commonService.batchInsert(dataList);
			}
		}
	}

	/**
	 * 判断当日护理计划 是否被执行
	 */
	@Transactional
	public void checkPlanToToday(CustomerNursingPlanModel model) {
		if (true) {
			throw new BusinessException(null, CommonConstants.ERROR_CODE.REPEAT_ERROR.label(), null);
		}
		Date dateTemp = new Date();
		if (model.getItems() != null && model.getItems().size() != 0) {
			for (NursingPlanServiceItem item : model.getItems()) {
				if (item != null && item.getDelStatus() != null && item.getDelStatus() != 1) {
					int weekIndex = CommonUtil.getWeekIndexFromSun(dateTemp);
					int year = dateTemp.getYear() + 1900;// 产生 年 周 序号
					int weekTab = CommonUtil.getWeek(dateTemp);

					// 验证当天护理计划是否被执行过
					int copyNowFlag = checkPlanDetailNowRelations(item.getCustomer().getId(), year,
							weekIndex, weekTab);
					if (copyNowFlag > 0) {
						throw new BusinessException(null,
								CommonConstants.ERROR_CODE.REPEAT_ERROR.label(), null);
					}
				}
			}
		}
	}

	/**
	 * 复制产生未来几周护理计划
	 */
	public void copyPlanToNextWeeks(CustomerNursingPlanModel model, int weeksNum) {
		logger.debug("start copy CustomerNursingPlanModel " + CommonUtil.getCurrTimeForString()
				+ " weekNum " + weeksNum);
		List dataList = new ArrayList<>();
		Date dateTemp = null;
		if (model.getItems() != null && model.getItems().size() != 0) {
			for (NursingPlanServiceItem item : model.getItems()) {
				if (item != null && item.getDelStatus() != null && item.getDelStatus() != 1) {
					for (int i = 0; i <= weeksNum; i++) {
						if (i == 0) {
							dateTemp = new Date();// i=0 本周 不复制 i=1是下周 2 3 4为后三周
						}
						int weekIndex = CommonUtil.getWeekIndexFromSun(dateTemp);
						int year = dateTemp.getYear() + 1900;// 产生 年 周 序号
						int weekTab = CommonUtil.getWeek(dateTemp);
						dateTemp = CommonUtil.getNextSaturday(dateTemp, 1);// 下周6的时间
						// 复制本周护理计划
						if (i == 0) {
							// 验证当天护理计划是否被执行过
							int copyNowFlag = checkPlanDetailNowRelations(item.getCustomer()
									.getId(), year, weekIndex, weekTab);
							if (item.getWeekTab() != null && item.getWeekTab() >= weekTab) {// 周计划
								int copyFlag = 1;
								// 当天已有计划被执行过不复制
								if (item.getWeekTab() == weekTab && copyNowFlag != 0) {
									copyFlag = 0;
								}
								if (copyFlag == 1) {
									NursingPlanDetail data = new NursingPlanDetail();
									data.setCreateDateTime(CommonUtil.getCurrTimes());
									data.setCustomer(item.getCustomer());
									data.setItem(item.getItem());
									data.setDelStatus((short) 0);
									data.setStartTimeTab(item.getStartTimeTab());
									data.setTenant(item.getTenant());
									data.setWeekTab(item.getWeekTab());// 周几
									data.setWeekIndex(weekIndex);// 第几周
									data.setYearTab(year);
									dataList.add(data);
								}
							}
							if (item.getWeekTab() == null) { // 日计划每天都有
								int k = weekTab + 1;
								if (copyNowFlag == 0) {
									k = weekTab;
								}
								for (; k < 7; k++) {
									NursingPlanDetail data = new NursingPlanDetail();
									data.setCreateDateTime(CommonUtil.getCurrTimes());
									data.setCustomer(item.getCustomer());
									data.setItem(item.getItem());
									data.setDelStatus((short) 0);
									data.setStartTimeTab(item.getStartTimeTab());
									data.setTenant(item.getTenant());
									data.setWeekTab(k);// 周几
									data.setWeekIndex(weekIndex);// 第几周
									data.setYearTab(year);
									dataList.add(data);
								} // end for k
							}
						}
						// 复制未来周护理计划
						if (i > 0) {
							if (item.getWeekTab() != null) {// 周计划
								NursingPlanDetail data = new NursingPlanDetail();
								data.setCreateDateTime(CommonUtil.getCurrTimes());
								data.setCustomer(item.getCustomer());
								data.setItem(item.getItem());
								data.setDelStatus((short) 0);
								data.setStartTimeTab(item.getStartTimeTab());
								data.setTenant(item.getTenant());
								data.setWeekTab(item.getWeekTab());// 周几
								data.setWeekIndex(weekIndex);// 第几周
								data.setYearTab(year);
								dataList.add(data);
							} else { // 日计划每天都有
								for (int k = 0; k < 7; k++) {
									NursingPlanDetail data = new NursingPlanDetail();
									data.setCreateDateTime(CommonUtil.getCurrTimes());
									data.setCustomer(item.getCustomer());
									data.setItem(item.getItem());
									data.setDelStatus((short) 0);
									data.setStartTimeTab(item.getStartTimeTab());
									data.setTenant(item.getTenant());
									data.setWeekTab(k);// 周几
									data.setWeekIndex(weekIndex);// 第几周
									data.setYearTab(year);
									dataList.add(data);
								} // end for k
							}
						} // end if i
					} // end for i
				} // end if item
			}
			if (dataList.size() > 0) {
				commonService.batchInsert(dataList); // 复制到后4周
			}
		}
	}

	/**
	 * 获取customer 的 定时服务项目
	 */
	public Iterable<NursingPlanDetail> getTimeServiceItemByCID(long customerId) {
		// Role role = userService.getRoleByUserId(userId);
		List<NursingPlanDetail> dataList = new ArrayList<NursingPlanDetail>();
		if (ActionContextHolder.getContext().getUser() != null
				&& ActionContextHolder.getContext().getUser().getId() != null) {
			long userId = ActionContextHolder.getContext().getUser().getId();
			Date now = new Date();
			Integer weekIndex = CommonUtil.getWeekIndexFromSun(now);// test
			Integer year = now.getYear() + 1900;
			Integer week = CommonUtil.getWeek(now);
			List<Long> customerList = new ArrayList<>();
			customerList.add(customerId);
			List<NursingPlanDetail> itemList = new ArrayList<NursingPlanDetail>();
			if (customerList.size() > 0) {
				// 获取当前护工所护理老人对应的 NursingPlanServiceItem
				StringBuilder queryDetail = new StringBuilder(
						"select c from NursingPlanDetail c "
								+ "where c.delStatus != ?1 and c.item.project.delStatus!=1 and c.yearTab=?2 and c.weekIndex=?3 and c.weekTab=?4 and c.customer.id in(:olds) ");
				itemList = this.em.createQuery(queryDetail.toString()).setParameter(1, (short) 1)
						.setParameter(2, year).setParameter(3, weekIndex).setParameter(4, week)
						.setParameter("olds", customerList).getResultList();
			}
			for (NursingPlanDetail item : itemList) {
				if (item != null) {
					StringBuilder queryRelation = new StringBuilder(
							"select c.serviceType.typecode from PositionServiceType c where c.position in (select u.employee.position from User u where u.id = ?1 )  ");
					List<String> serviceTypeList = this.em.createQuery(queryRelation.toString())
							.setParameter(1, userId).getResultList();
					// 判断item所属position和 user所关联Employee position一致 huibati
					if (item.getItem().getItem().getServiceType() != null
							&& !"countTypeByFrequency".equals(item.getItem().getItem()
									.getCountType().getTypecode())) {
						if (serviceTypeList.contains(item.getItem().getItem().getServiceType()
								.getTypecode())) {// item角色类型与当前staff所属角色类型一致
													// -----判断item所属position和
													// user所关联Employee
													// position一致
							dataList.add(item);
						}
					}
				}
			}
		}
		return dataList;
	}

	/**
	 * 获取user的定时服务项目
	 */
	public Iterable<NursingPlanDetail> getTimeServiceItemByUID(long userId) {
		// Role role = userService.getRoleByUserId(userId);
		Date now = new Date();
		Integer weekIndex = CommonUtil.getWeekIndexFromSun(now);// test
		Integer year = now.getYear() + 1900;
		Integer week = CommonUtil.getWeek(now);
		// if(week==0) week=7;
		// huibati 获取 user所对应 employee 在获取 employee所对应customer
		List<NursingPlanDetail> dataList = new ArrayList<NursingPlanDetail>();
		StringBuilder queryCustomer = new StringBuilder(
				"select c from Customer c where c.delStatus != 1 and  c.customerStatus is not null and c.customerStatus.typecode!=?3 and c.bed in ( select b from Bed b where b.delStatus != ?1 "
						+ "and b in( select n.bed from BedNurseGroup n where n.delStatus != ?1 "
						+ "and n.group in( select c.group from EmployeeNursingGroup c where c.delStatus != 1 and c.employee in (select u.employee from User u where u.id = ?2 )) "
						+ "))");
		List<Customer> customerList = this.em.createQuery(queryCustomer.toString())
				.setParameter(1, (short) 1).setParameter(2, userId)
				.setParameter(3, "customerStatusOut").getResultList();//
		List<NursingPlanDetail> itemList = new ArrayList<NursingPlanDetail>();
		if (customerList.size() > 0) {
			// 获取当前护工所护理老人对应的 NursingPlanServiceItem
			StringBuilder queryDetail = new StringBuilder(
					"select c from NursingPlanDetail c "
							+ "where c.delStatus != ?1 and c.item.project.delStatus!=1 and c.yearTab=?2 and c.weekIndex=?3 and c.weekTab=?4 and c.customer in(:olds) ");
			itemList = this.em.createQuery(queryDetail.toString()).setParameter(1, (short) 1)
					.setParameter(2, year).setParameter(3, weekIndex).setParameter(4, week)
					.setParameter("olds", customerList).getResultList();
		}
		for (NursingPlanDetail item : itemList) {
			if (item != null) {
				StringBuilder queryRelation = new StringBuilder(
						"select c.serviceType.typecode from PositionServiceType c where c.position in (select u.employee.position from User u where u.id = ?1 )  ");
				List<String> serviceTypeList = this.em.createQuery(queryRelation.toString())
						.setParameter(1, userId).getResultList();
				// 判断item所属position和 user所关联Employee position一致 huibati
				if (item.getItem().getItem().getServiceType() != null
						&& !"countTypeByFrequency".equals(item.getItem().getItem().getCountType()
								.getTypecode())) {
					if (serviceTypeList.contains(item.getItem().getItem().getServiceType()
							.getTypecode())) {
						dataList.add(item);
					}
				}
			}
		}
		return dataList;
	}

	/**
	 * 获取不定时服务
	 */
	public Iterable<NursingPlanDetail> getCountServiceItem(long userId) {
		Role role = userService.getRoleByUserId(userId);
		Integer weekIndex = CommonUtil.getWeekIndexFromSun(new Date());//
		Integer year = new Date().getYear() + 1900;
		Integer week = CommonUtil.getWeek(new Date());
		// if(week==0) week=7;
		List<NursingPlanDetail> itemList = new ArrayList<NursingPlanDetail>();
		// huibati 获取 user所对应 employee 在获取 employee所对应customer
		StringBuilder queryCustomer = new StringBuilder(
				"select c from Customer c where c.delStatus != 1 "
						+ "and c.bed in ( select b from Bed b where b.delStatus != ?1 and b in( select n.bed from BedNurseGroup n where n.delStatus != ?1 "
						+ "and n.group in( select c.group from EmployeeNursingGroup c where c.delStatus != 1 and c.employee in (select u.employee from User u where u.id = ?2 )) "
						+ "))");
		List<Customer> customerList = this.em.createQuery(queryCustomer.toString())
				.setParameter(1, (short) 1).setParameter(2, userId).getResultList();
		if (customerList.size() > 0) {
			// 获取当前护工所护理老人对应的 NursingProjectServiceItem 通过角色类型进行过滤
			StringBuilder queryDetail = new StringBuilder(
					"select c from NursingPlanDetail c "
							+ "where c.delStatus != ?1 "
							+ "and c.item.project.delStatus!=1 and c.yearTab=?2 and c.weekIndex=?3 and c.weekTab=?4 "
							+ "and c.customer in(:olds) ");
			List<NursingPlanDetail> list = this.em.createQuery(queryDetail.toString())
					.setParameter(1, (short) 1).setParameter(2, year).setParameter(3, weekIndex)
					.setParameter(4, week).setParameter("olds", customerList).getResultList();
			for (int i = 0; i < list.size(); i++) {
				NursingPlanDetail item = list.get(i);
				if (item == null) {
					logger.debug("null-----------------------------------------------");
				} else {
					StringBuilder queryRelation = new StringBuilder(
							"select c.serviceType.typecode from PositionServiceType c "
									+ "where c.position in (select u.employee.position from User u where u.id = ?1 )  ");
					List<String> serviceTypeList = this.em.createQuery(queryRelation.toString())
							.setParameter(1, userId).getResultList();
					if (serviceTypeList.size() > 0) {
						if ("countTypeByFrequency".equals(item.getItem().getItem().getCountType()
								.getTypecode())) {
							// 修改为
							// item所对应的Servicetype与当前user所对应的Employee的岗位所对应的Servicetype一致
							if (item.getItem().getItem().getServiceType() != null) {
								if (serviceTypeList.contains(item.getItem().getItem()
										.getServiceType().getTypecode())) {
									itemList.add(item);
								}
							}
						} // end count
					}
				}
			}
		}
		return itemList;
	}

	/**
	 * 验证护理等级关联关系
	 */
	public int checkLevelRelations(NursingLevel level) {
		int flag = 0;
		Long id = level.getId();
		List projectList = new ArrayList<>();
		projectList = this.em
				.createQuery(
						"select c from NursingProject c where c.delStatus != ?1 and c.tenant.id=?2 and c.level.id=?3 ")
				.setParameter(1, (short) 1)
				.setParameter(2, ActionContextHolder.getContext().getTenantId())
				.setParameter(3, id).getResultList();

		List scopeList = new ArrayList<>();
		scopeList = this.em
				.createQuery(
						"select c from EvaluateScoreScope c where c.delStatus != ?1 and c.tenant.id=?2 and c.level.id=?3 ")
				.setParameter(1, (short) 1)
				.setParameter(2, ActionContextHolder.getContext().getTenantId())
				.setParameter(3, id).getResultList();

		List resultList = new ArrayList<>();
		resultList = this.em
				.createQuery(
						"select c from EvaluateResult c where c.delStatus != ?1 and c.tenant.id=?2 and c.level.id=?3 ")
				.setParameter(1, (short) 1)
				.setParameter(2, ActionContextHolder.getContext().getTenantId())
				.setParameter(3, id).getResultList();
		flag += projectList.size() + scopeList.size() + resultList.size();

		return flag;
	}

	/**
	 * 获取老人相应周的护理计划 数量
	 */
	public Iterable<NursingPlanDetail> getCustomerNursePlanNum(long customerId, Integer yearTab,
			Integer weekIndex) {
		Map<Integer, NursingPlanDetail> dataMap = new HashMap<Integer, NursingPlanDetail>();// 每天
																							// 日计划
																							// 周计划相应数量
		Map<NursingProjectServiceItem, Integer> detailWeekCounts = new HashMap<NursingProjectServiceItem, Integer>();// 统计周计划本周安排次数
		int tempId = 7;
		for (int i = 0; i < 7; i++) {// 0-6 对应周末--周六
			NursingPlanDetail detail = new NursingPlanDetail();
			detail.setYearTab(yearTab);// 年份
			detail.setWeekIndex(weekIndex);// 第几周
			detail.setWeekTab(i);// 周几
			detail.setWeekPlanNum(0);
			detail.setDayPlanNum(0);
			detail.setId(new Long(i));
			dataMap.put(i, detail);
		}
		List<NursingPlanDetail> dataList = new ArrayList<NursingPlanDetail>();
		StringBuilder queryDetail = new StringBuilder(
				"select c from NursingPlanDetail c "
						+ "where c.delStatus != ?1 and c.yearTab=?2 and c.weekIndex=?3  and c.customer.id= ?4  ");
		dataList = this.em.createQuery(queryDetail.toString()).setParameter(1, (short) 1)
				.setParameter(2, yearTab).setParameter(3, weekIndex).setParameter(4, customerId)
				.getResultList();
		String weekItemName = " ";
		String dayItemName = " ";
		if (dataList != null) {
			for (NursingPlanDetail detail : dataList) {
				if (detail != null && detail.getItem() != null
						&& detail.getItem().getItem() != null
						&& detail.getItem().getItem().getPeriod() != null) {
					if ("periodWeek".equals(detail.getItem().getItem().getPeriod().getTypecode())) {// 周计划
						if (detailWeekCounts.containsKey(detail.getItem())) {
							detailWeekCounts.put(detail.getItem(),
									detailWeekCounts.get(detail.getItem()) + 1);
						} else {
							detailWeekCounts.put(detail.getItem(), 1);
						}
						if (weekItemName.contains(detail.getItem().getItem().getName() + ",")) {

						} else {
							weekItemName += detail.getItem().getItem().getName() + ",";
						}
						int weekPlanNum = dataMap.get(detail.getWeekTab()).getWeekPlanNum();
						dataMap.get(detail.getWeekTab()).setWeekPlanNum(weekPlanNum + 1);
					}
					if ("periodDay".equals(detail.getItem().getItem().getPeriod().getTypecode())) {// 天计划
						if (dayItemName.contains(detail.getItem().getItem().getName() + ",")) {

						} else {
							dayItemName += detail.getItem().getItem().getName() + ",";
						}
						int dayPlanNum = dataMap.get(detail.getWeekTab()).getDayPlanNum();
						dataMap.get(detail.getWeekTab()).setDayPlanNum(dayPlanNum + 1);
					}
				}
			}
		}
		if (dayItemName.length() > 0) {
			dayItemName = dayItemName.substring(0, dayItemName.length() - 1);
		}
		if (weekItemName.length() > 0) {
			weekItemName = weekItemName.substring(0, weekItemName.length() - 1);
		}
		dataMap.get(0).setRemark(weekItemName + "@" + dayItemName);
		if (detailWeekCounts.size() > 0) {
			Set<NursingProjectServiceItem> keySet = detailWeekCounts.keySet();
			for (NursingProjectServiceItem key : keySet) {
				NursingPlanDetail detail = new NursingPlanDetail();
				detail.setItem(key);
				detail.setWeekCounts(detailWeekCounts.get(key));
				detail.setId(new Long(tempId));
				dataMap.put(tempId, detail);
				tempId++;
			}
		}
		return new ArrayList<NursingPlanDetail>(dataMap.values());
	}

	/**
	 * 验证serviceItem是否有关联
	 */
	public int checkServiceItemRelations(CustomerServiceItem item) {
		int flag = 0;
		Long id = item.getId();
		List projectList = new ArrayList<>();
		projectList = this.em
				.createQuery(
						"select c from NursingProjectServiceItem c where c.delStatus != ?1  and c.item.id=?2 ")
				.setParameter(1, (short) 1).setParameter(2, id).getResultList();
		List levelList = new ArrayList<>();
		levelList = this.em
				.createQuery(
						"select c from NursingLevelServiceItem c where c.delStatus != ?1  and c.item.id=?2 ")
				.setParameter(1, (short) 1).setParameter(2, id).getResultList();
		flag += projectList.size() + levelList.size();
		return flag;
	}

	/**
	 * 验证serviceItem是否居家订单关联
	 */
	public int checkServiceItemRelationsJujia(CustomerServiceItem item) {
		int flag = 0;
		Long id = item.getId();
		List detailtList = new ArrayList<>();
		String sqlString = "select * from ( select * from tnb_nursingproject_serviceitem where id in( select item_id from tnb_nursingplan_detail)) a where a.serviceitem_id = " + id + " and a.del_status = 0";
		detailtList = this.em.createNativeQuery(sqlString).getResultList();
		flag += detailtList.size();
		return flag;
	}

	/**
	 * 验证foodlevel是否有关联
	 */
	public int checkFoodLevelRelations(DicttypeTenant level) {
		int flag = 0;
		Long id = level.getId();
		List levelList = new ArrayList<>();
		StringBuilder queryCustomer = new StringBuilder(
				"select c from Customer c where c.delStatus != ?1  and c.diningStandard.id=?2 ");
		levelList = this.em.createQuery(queryCustomer.toString()).setParameter(1, (short) 1)
				.setParameter(2, id).getResultList();
		flag += levelList.size();
		return flag;
	}

	// /**
	// * 验证project是否和plandetail有关联
	// */
	// public int checkProjectRelations(NursingProject project) {
	// int flag = 0;
	// Long id = project.getId();
	// List projectList = new ArrayList<>();
	// StringBuilder queryDetail = new StringBuilder(
	// "select c from NursingPlanDetail c where c.delStatus != ?1  and c.item.project.id=?2 ");
	// projectList = this.em.createQuery(queryDetail.toString()).setParameter(1,
	// (short) 1)
	// .setParameter(2, id).getResultList();
	// flag += projectList.size();
	// return flag;
	// }

	/**
	 * @author huibati 删除Project 2017年7月19日
	 */
	@Transactional
	public void deleteNursingProject(NursingProject project) {
		StringBuilder queryItem = new StringBuilder(
				"update  NursingProjectServiceItem rp set rp.delStatus=1 where rp.project.id = ?1 and rp.delStatus=?2 ");
		this.em.createQuery(queryItem.toString()).setParameter(1, project.getId())
				.setParameter(2, (short) 0).executeUpdate();
		StringBuilder queryProject = new StringBuilder(
				"update  NursingProject rp set rp.delStatus=1 where rp.id = ?1 ");
		this.em.createQuery(queryProject.toString()).setParameter(1, project.getId())
				.executeUpdate();
	}

	/**
	 * 验证projectitem是否和plandetail有关联
	 */
	public int checkProjectItemRelations(Customer customer, List<Long> itemIds, int dateTime) {

		List modelList = new ArrayList<>(); // 检查护理模版是否包含
		StringBuilder queryDetail = new StringBuilder(
				"select n from NursingPlanServiceItem n where n.delStatus != ?1 and n.customer.id = ?2  and n.item.id in (:ids) ");
		modelList = this.em.createQuery(queryDetail.toString()).setParameter(1, (short) 1)
				.setParameter(2, customer.getId()).setParameter("ids", itemIds).getResultList();

		return modelList.size();
	}

	/**
	 * 获取
	 */
	public NurseMerch getNurseMerchByCode(NurseMerch data) {
		StringBuilder query = new StringBuilder(
				"select c from NurseMerch c where c.code = ?1 and c.delStatus != ?2 and c.type.typecode = ?3 and c.tenant.id = ?4 ");
		List dataList = this.em.createQuery(query.toString()).setParameter(1, data.getCode())
				.setParameter(2, (short) 1).setParameter(3, data.getType().getTypecode())
				.setParameter(4, ActionContextHolder.getContext().getTenantId()).getResultList();
		NurseMerch ct = null;
		if (dataList.size() > 0) {
			ct = (NurseMerch) dataList.get(0);
		}

		return ct;
	}

	/**
	 * 获取
	 */
	public NurseMerch getNurseMerchByCodeFilterId(NurseMerch data) {
		StringBuilder query = new StringBuilder(
				"select c from NurseMerch c where c.code = ?1 and c.delStatus != ?2  and c.id != ?3 and c.type.typecode = ?4 and c.tenant.id = ?5  ");
		List dataList = this.em.createQuery(query.toString()).setParameter(1, data.getCode())
				.setParameter(2, (short) 1).setParameter(3, data.getId())
				.setParameter(4, data.getType().getTypecode())
				.setParameter(5, ActionContextHolder.getContext().getTenantId()).getResultList();
		NurseMerch ct = null;
		if (dataList.size() > 0) {
			ct = (NurseMerch) dataList.get(0);
		}
		return ct;
	}

	/**
	 * 获取老人 projectitem 不定时任务
	 */
	public List<NursingProjectServiceItem> getProjectItemByCustomer(List<Long> customerList,
			String positonType, String itemType) {
		List<NursingProjectServiceItem> itemList = new ArrayList<NursingProjectServiceItem>();
		List<String> serviceTypeList = new ArrayList<>();
		if (customerList != null && customerList.size() > 0) {
			// 相应岗位对应的服务项目类别
			if (positonType != null && !"".equals(positonType)) {
				StringBuilder queryRelation = new StringBuilder(
						"select c.serviceType.typecode from PositionServiceType c where c.position.typecode =?1");
				serviceTypeList = this.em.createQuery(queryRelation.toString())
						.setParameter(1, positonType).getResultList();
			}
			if (itemType != null && !"".equals(itemType)) {
				String[] types = itemType.split(",");
				for (String type : types) {
					if (!"".equals(type)) {
						serviceTypeList.add(type);
					}
				}
			}
			// 老人对应的 NursingProjectServiceItem
			StringBuilder queryItem = new StringBuilder(
					"select item from NursingProjectServiceItem item JOIN FETCH item.project project "
							+ "where item.delStatus != ?1 and project.customer.id in (:olds) and item.item.countType.typecode = ?3");
			itemList = this.em.createQuery(queryItem.toString()).setParameter(1, (short) 1)
					.setParameter("olds", customerList).setParameter(3, "countTypeByFrequency")
					.getResultList();
			if (serviceTypeList.size() > 0 && itemList.size() > 0) {
				for (Iterator<NursingProjectServiceItem> it = itemList.iterator(); it.hasNext();) {
					NursingProjectServiceItem item = it.next();
					if (!serviceTypeList.contains(item.getItem().getServiceType().getTypecode())) {
						it.remove();
					}
				}
			}
		}
		return itemList;
	}

	/**
	 * 获取老人 NursingPlanDetail 定时任务
	 */
	public List<NursingPlanDetail> getPlanDetailByCustomer(List<Long> customerList,
			String positonType, String itemType) {
		List<NursingPlanDetail> dataList = new ArrayList<NursingPlanDetail>();
		List<String> serviceTypeList = new ArrayList<>();
		if (customerList != null && customerList.size() > 0) {
			// 相应岗位对应的服务项目类别
			if (positonType != null && !"".equals(positonType)) {
				StringBuilder queryRelation = new StringBuilder(
						"select c.serviceType.typecode from PositionServiceType c where c.position.typecode =?1");
				serviceTypeList = this.em.createQuery(queryRelation.toString())
						.setParameter(1, positonType).getResultList();
			}
			if (itemType != null && !"".equals(itemType)) {
				String[] types = itemType.split(",");
				for (String type : types) {
					if (!"".equals(type)) {
						serviceTypeList.add(type);
					}
				}
			}
			Date now = new Date();
			Integer weekIndex = CommonUtil.getWeekIndexFromSun(now);// test
			Integer year = now.getYear() + 1900;
			Integer week = CommonUtil.getWeek(now);
			// 获取老人对应的 NursingPlanDetail
			StringBuilder queryDetail = new StringBuilder(
					"select c from NursingPlanDetail c "
							+ " where c.delStatus != ?1 and c.item.project.delStatus!=1 "
							+ " and c.yearTab=?2 and c.weekIndex=?3 and c.weekTab=?4 and c.customer.id in (:olds) "
							+ " and c.customer.id = c.item.project.customer.id"
							+ " and c.item.item.countType.typecode != ?6 ");
			dataList = this.em.createQuery(queryDetail.toString()).setParameter(1, (short) 1)
					.setParameter(2, year).setParameter(3, weekIndex).setParameter(4, week)
					.setParameter("olds", customerList).setParameter(6, "countTypeByFrequency")
					.getResultList();
			if (serviceTypeList.size() > 0 && dataList.size() > 0) {
				for (Iterator<NursingPlanDetail> it = dataList.iterator(); it.hasNext();) {
					NursingPlanDetail detail = it.next();
					if (!serviceTypeList.contains(detail.getItem().getItem().getServiceType()
							.getTypecode())) {
						it.remove();
					}
				}
			}
		}
		return dataList;
	}

	/**
	 * 获取老人 CustomerDrugProject 用药计划
	 */
	public List<CustomerDrugProject> getDrugProjectByCustomer(List<Long> customerList,
			String positonType, String itemType) {
		List<CustomerDrugProject> dataList = new ArrayList<CustomerDrugProject>();
		// zhuanyehuli 查看用药计划
		// if (positonType == null || !"postType5".equals(positonType)) {
		if (itemType != null && "serviceType1".equals(itemType)) {
			if (customerList != null && customerList.size() > 0) {
				StringBuilder query = new StringBuilder(
						"select  c  from CustomerDrugProject c  where c.delStatus != ?1  "
								+ " and  c.customerDrug.customer.id in (:olds)");
				dataList = this.em.createQuery(query.toString()).setParameter(1, (short) 1)
						.setParameter("olds", customerList).getResultList();
			}
		}
		return dataList;
	}

	/**
	 * 获取 老人 定时任务,不定时任务以及用药计划
	 */
	public List<SpecService> getNursingServiceByCustomer(Long customerId, Long userId,
			Long queryStartDate, Long queryEndDate, String positonType, String itemType,
			String flagQueryType) {
		String curTime = CommonUtil.getCurrTimeForString();// 当日日期
		Integer curTimeStart = 0;
		Integer curTimeEnd = 0;
		Integer curMonTimeStart = 0;
		Integer curMonTimeEnd = 0;
		try {
			curTimeStart = CommonUtil.strToIntegerTime(curTime.substring(0, 10) + " 00:00:00");
			curTimeEnd = CommonUtil.strToIntegerTime(curTime.substring(0, 10) + " 23:59:59");
			// curMonTimeStart = CommonUtil
			// .strToIntegerTime(CommonUtil.getMonthFirstDayForString().substring(0,
			// 10) + " 00:00:00");
			// curMonTimeEnd = CommonUtil
			// .strToIntegerTime(CommonUtil.getMonthLastDayForString().substring(0,
			// 10) + " 23:59:59");
		} catch (ParseException e) {
			logger.error("timer error " + e);
		}
		
		List<NursingPlanDetail> detailList = new ArrayList<NursingPlanDetail>();// 护理计划
		List<CustomerDrugProject> projectList = new ArrayList<CustomerDrugProject>();// 用药计划
		List<NursingProjectServiceItem> itemList = new ArrayList<NursingProjectServiceItem>();// 不定时任务
		List<NursingPlanExecute> detailExeList = new ArrayList<NursingPlanExecute>();// 定时任务完成情况
		List<NursingPlanExecute> itemExeList = new ArrayList<NursingPlanExecute>();// 不定时任务完成情况
		List<CustomerDrugProjectExe> drugExeList = new ArrayList<CustomerDrugProjectExe>();// drug完成情况
		Map<String, CustomerDrugProjectExe> drugExeMap = new HashMap<>();// customerdrugid+@+计划用药时间
		Map<String, List<NursingPlanExecute>> planExeMap = new HashMap<>();// projextItemid+执行情况/projextItemid+#+planexedate+执行情况
		List<Long> customerList3 = new ArrayList<>();
		if (customerId != null) {
			customerList3.add(customerId);
		} else {
			// 护理组所护理的老人
			// customerList = getCustomerByUID(userId);
			// 根据班次获取当前user护理哪些老人
			customerList3 = getCustomerByUID(userId, CommonUtil.getCurrTimes());
			// 去重
			// customerList =
			// customerList.stream().distinct().collect(Collectors.toList());
		}
		List<Long> customerList2 = new ArrayList<>();
		for(Long id : customerList3) {
			// 判断老人是否请假
			List<SpecService> dataList = new ArrayList<SpecService>();
			Map<String, Object> params = Maps.newHashMap();
			params.put("customer.id", id);
			params.put("status", LeaveStatus.LEAVING.getValue());
			params.put("delStatus", CommonConstants.DEL_STATUS_NO_0);
			String querySb = buildQueryStr(params, "CustomerLeave");
			List<CustomerLeave> list = this.em.createQuery(querySb).getResultList();
			if(!(list != null && list.size() > 0)) {
				customerList2.add(id);
			} 
		}
		
		List<SpecService> dataList = new ArrayList<SpecService>();
		if(customerList2.size() == 0) {
			return dataList;
		}
		
		if (customerList2 != null && customerList2.size() > 0) {
			StringBuilder queryStr = new StringBuilder(
					"select  c3 from Conf c3 where c3.delStatus=0 " + " and c3.code='drugDay'  ");
			List conf = this.em.createQuery(queryStr.toString()).getResultList();
			Long idTemp = (long) 1;
			logger.debug("querytest flagQueryType " + flagQueryType);
			if (flagQueryType == null || "".equals(flagQueryType)
					|| flagQueryType.contains("dingshi") || flagQueryType.contains("all")) {
				logger.debug("querytest dingshi");
				projectList = getDrugProjectByCustomer(customerList2, positonType, itemType);// 用药计划
				detailList = getPlanDetailByCustomer(customerList2, positonType, itemType);// 定时任务
			}
			if (flagQueryType == null || "".equals(flagQueryType)
					|| flagQueryType.contains("suishi") || flagQueryType.contains("all")) {
				logger.debug("querytest suishi");
				itemList = getProjectItemByCustomer(customerList2, positonType, itemType);// 不定时任务
			}
			if (projectList != null && projectList.size() > 0) {
				// 获取当日用药计划执行情况
				StringBuilder drugExe = new StringBuilder("select c from CustomerDrugProjectExe c "
						+ " where c.delStatus != ?1 and c.customerDrug.customer.id in (:olds) "
						+ " and c.createDateTime >= ?3 and c.createDateTime <= ?4 ");
				drugExeList = this.em.createQuery(drugExe.toString()).setParameter(1, (short) 1)
						.setParameter("olds", customerList2).setParameter(3, curTimeStart)
						.setParameter(4, curTimeEnd).getResultList();
				// 拼接map,key:customerdrugid+@+计划用药时间
				for (int i = 0; i < drugExeList.size(); i++) {
					drugExeMap.put(drugExeList.get(i).getCustomerDrug().getId().toString() + "@"
							+ drugExeList.get(i).getUseDrugDate(), drugExeList.get(i));
				}
				// 拆分 CustomerDrugProject
				for (CustomerDrugProject project : projectList) {
					if (project != null && project.getUseDrugDate() != null
							&& !"".equals(project.getUseDrugDate())) {
						String[] dates = project.getUseDrugDate().split(",");
						for (String date : dates) {
							if (date != null && date.matches("\\d+")) {
								CustomerDrugProjectItem projectTemp = new CustomerDrugProjectItem();
								BeanUtils.copyProperties(project, projectTemp);
								projectTemp.setUseDrugDate(date);
								projectTemp.setId(idTemp);
								projectTemp.setProject(project);
								SpecService temp = new SpecService();
								if (drugExeMap.containsKey(project.getCustomerDrug().getId() + "@"
										+ date)) {
									temp.setDrugExe(drugExeMap.get(project.getCustomerDrug()
											.getId() + "@" + date));
								}
								temp.setProject(projectTemp);
								temp.setId(idTemp);

								double useDrugNum = project.getUseDrugNum();
								double useDrugFreq = project.getUseDrugFreq();
								double drugNum = project.getCustomerDrug().getDrugNum();
								Conf fConf = ((Conf) conf.get(0));
								double dayNum = Double.parseDouble(fConf.getValue());
								if (drugNum <= dayNum * useDrugFreq * useDrugNum) {
									int days = 0;
									if (drugNum <= 0) {

									} else {
										days = (int) (drugNum / (useDrugFreq * useDrugNum));
									}
									temp.setRemark(days + "");
								}
								dataList.add(temp);
								idTemp++;
							} // end if date
						} // end for data
					} // end if project
				} // end for project
			}
			// 获取当日任务planexe执行情况
			StringBuilder queryDetailExe = new StringBuilder("select c from NursingPlanExecute c "
					+ " where c.delStatus != ?1  and c.itemProject.project.customer.id in (:olds) "
					+ " and c.createDateTime >= ?3 and c.createDateTime <= ?4 ");
			detailExeList = this.em.createQuery(queryDetailExe.toString())
					.setParameter(1, (short) 1).setParameter("olds", customerList2)
					.setParameter(3, curTimeStart).setParameter(4, curTimeEnd).getResultList();
			// 拼接map,key:projextItemid(不定时)/projextItemid+#+planexedate(定时)
			if (detailExeList != null && detailExeList.size() > 0) {
				for (int i = 0; i < detailExeList.size(); i++) {
					if (detailExeList.get(i).getPlanExeDate() != null
							&& detailExeList.get(i).getPlanExeDate().matches("\\d+")) {// 定时任务执行
						List<NursingPlanExecute> exes = new ArrayList<>();
						exes.add(detailExeList.get(i));
						planExeMap.put(detailExeList.get(i).getItemProject().getId().toString()
								+ "#" + detailExeList.get(i).getPlanExeDate(), exes);
					} else {
						if (planExeMap
								.get(detailExeList.get(i).getItemProject().getId().toString()) == null) {//
							List<NursingPlanExecute> exes = new ArrayList<>();
							exes.add(detailExeList.get(i));
							planExeMap.put(
									detailExeList.get(i).getItemProject().getId().toString(), exes);
						} else {
							planExeMap
									.get(detailExeList.get(i).getItemProject().getId().toString())
									.add(detailExeList.get(i));
						}
					}
				}
			}
			for (NursingPlanDetail detail : detailList) {
				if (detail != null && detail.getStartTimeTab() != null
						&& !"".equals(detail.getStartTimeTab())) {
					SpecService temp = new SpecService();
					if (planExeMap.containsKey(detail.getItem().getId().toString() + "#"
							+ detail.getStartTimeTab())) {
						temp.setItemExes(planExeMap.get(detail.getItem().getId().toString() + "#"
								+ detail.getStartTimeTab()));
					}
					temp.setId(idTemp);
					temp.setItem(detail);
					dataList.add(temp);
					idTemp++;
				}
			} // end for detail
			for (NursingProjectServiceItem item : itemList) {
				if (item != null) {
					SpecService temp = new SpecService();
					if (planExeMap.containsKey(item.getId().toString())) {
						// temp.setItemExe(planExeMap.get(item.getId().toString()));
						temp.setItemExes(planExeMap.get(item.getId().toString()));
					}
					temp.setId(idTemp);
					temp.setProjectItem(item);
					dataList.add(temp);
					idTemp++;
				}
			} // end for item
				// 根据时间间隔以及完成未完成条件进行筛选
			if (queryStartDate != null && queryEndDate != null) {
				for (Iterator<SpecService> it = dataList.iterator(); it.hasNext();) {
					SpecService spec = it.next();

					if (spec != null) {
						if (spec.getProjectItem() != null) {
							continue;
						}
						if (spec.getDate() >= queryStartDate && spec.getDate() <= queryEndDate) {

						} else {
							it.remove();
							continue;
						}
						if (flagQueryType != null && !"".equals(flagQueryType)
								&& flagQueryType.contains("unDone")) {// 未完成
							if (spec.getDrugExe() == null
									|| (spec.getItemExes() == null || spec.getItemExes().size() == 0)) {

							} else {
								it.remove();
								continue;
							}
						}
						if (flagQueryType != null && !"".equals(flagQueryType)
								&& flagQueryType.contains("done")) {// 完成
							if (spec.getDrugExe() != null
									|| (spec.getItemExes() != null && spec.getItemExes().size() >= 0)) {

							} else {
								it.remove();
							}
						}
					}
				}
			}
			// 按照时间排序
			Collections.sort(dataList);
		} // end if culist
		return dataList;
	}
	
	/**
	 * 构建查询语句
	 *
	 * @author ytche
	 * @param param
	 * @return
	 * @date 2017年6月16日 下午4:48:09
	 */
	private String buildQueryStr(Map<String, Object> param, String name) {
		StringBuilder querySb = new StringBuilder("from ").append(name).append(
				" as t ");
		if (param == null || param.size() < 1) {
			return querySb.toString();
		}
		querySb.append(" where ");
		int index = 0;
		for (Entry<String, Object> entry : param.entrySet()) {
			if (index != 0) {
				querySb.append(" and ");
			}
			querySb.append(" t.").append(entry.getKey()).append("='")
					.append(entry.getValue()).append("' ");
			index++;
		}
		return querySb.toString();
	}
	
	/**
	 * 根据user对应employee所处护理组获取user照料老人 user->employee employee +
	 * EmployeeNursingGroup->group group + BedNurseGroup->bed bed -> customer
	 */
	public List<Long> getCustomerByUID(long userId) {
		StringBuilder queryCustomer = new StringBuilder(
				"select c.id from Customer c where c.delStatus != 1 and  c.customerStatus is not null and c.customerStatus.typecode!=?3  and c.bed in ( select b from Bed b where b.delStatus != ?1 "
						+ "and b in( select n.bed from BedNurseGroup n where n.delStatus != ?1 "
						+ "and n.group in( select c.group from EmployeeNursingGroup c where c.delStatus != 1 and c.employee in (select u.employee from User u where u.id = ?2 )) "
						+ ")) and c not in ( select cl.customer from CustomerLeave cl where cl.delStatus != 1 and cl.tenant.id=c.tenant.id and cl.status=1)");
		List<Long> customerList = this.em.createQuery(queryCustomer.toString())
				.setParameter(1, (short) 1).setParameter(2, userId)
				.setParameter(3, "customerStatusOut").getResultList();
		return customerList;
	}

	/**
	 * 根据user对应employee所当天以及昨天跨天排班获取user照料老人 区分职位 user->employee employee +
	 * StaffSchedule-> workTimeSetting workTimeSetting + BedWorkTimeSetting ->
	 * bed bed -> customer
	 */
	public List<Long> getCustomerByUID(long userId, Integer dateTime) {
		User user = new User();
		user.setId(userId);
		StringBuilder sql = new StringBuilder(
				" select c.employee from User c where c.delStatus!=1  and c.id=?1 ");
		List<Employee> saList = this.em.createQuery(sql.toString()).setParameter(1, userId)
				.getResultList();
		Employee staff = saList == null || saList.size() == 0 ? null : saList.get(0);
		Date now = new Date(dateTime * 1000L);
		Integer weekIndex = CommonUtil.getWeekIndexFromSun(now);// 第几周
		Integer yearTab = now.getYear() + 1900;
		Integer weekTab = CommonUtil.getWeek(now);// 周几
		// 昨天的年周以及周几
		Integer proWeekIndex = weekIndex;
		Integer proYearTab = yearTab;
		Integer proWeekTab = weekTab - 1;
		if (proWeekTab == -1) {
			proWeekTab = 6;
			proWeekIndex -= 1;
			if (proWeekIndex == 0) {
				proWeekIndex = 52;
				proYearTab -= 1;
			}
		}
		List<Long> customerList = new ArrayList<>();
		StringBuilder queryCustomer = new StringBuilder();
		String isAdmin = "0";
		if (staff != null && staff.getSalaryPosition() != null) {
			isAdmin = staff.getSalaryPosition().getIsAdmin();
			isAdmin = isAdmin == null ? "0" : isAdmin;
		}
		if (!isAdmin.equals("1")) {
			// 当天班次护理老人
			queryCustomer
					.append("select c.id from Customer c where c.delStatus != 1 and  c.customerStatus is not null and c.customerStatus.typecode!=?1  and c.bed in ( select b from Bed b where b.delStatus != 1 "
							+ "and b in( select n.bed from BedWorkTimeSetting n where n.delStatus != 1 "
							+ "and n.setting in( select c.workTimeSetting from StaffSchedule c where c.delStatus != 1 and (( c.year = ?2  and c.weekIndex = ?3 and c.week = ?4 ) or ( c.year=?6 and c.weekIndex=?7 and c.week=?8 and c.workTimeSetting.ktFlag=1 ) )and c.employee in (select u.employee from User u where u.id = ?5 )) "
							+ ")) and c not in ( select cl.customer from CustomerLeave cl where cl.delStatus != 1 and cl.tenant.id=c.tenant.id and cl.status=1)");
			customerList = this.em.createQuery(queryCustomer.toString())
					.setParameter(1, "customerStatusOut").setParameter(2, yearTab)
					.setParameter(3, weekIndex).setParameter(4, weekTab).setParameter(5, userId)
					.setParameter(6, proYearTab).setParameter(7, proWeekIndex)
					.setParameter(8, proWeekTab).getResultList();
		} else {
			// 所有老人
			queryCustomer
					.append("select c.id from Customer c where c.delStatus != 1 and  c.customerStatus is not null"
							+ " and (c.customerStatus.typecode=?1 or c.customerStatus.typecode=?2 or c.customerStatus.typecode=?4)"
							+ " and c.tenant in (select u.tenant from User u where u.id = ?3 )");
			customerList = this.em.createQuery(queryCustomer.toString())
					.setParameter(1, "customerStatusIn").setParameter(2, "customerStatusTry")
					.setParameter(3, userId).setParameter(4, "customerStatusTryWaitIn")
					.getResultList();
		}

		return customerList;
	}

	/**
	 * 验证医疗物品关联关系
	 */
	public int checkNurseMerchRelations(NurseMerch data) {
		int flag = 0;
		List resultList = new ArrayList<>();
		resultList = this.em
				.createQuery(
						" select c from ServiceMerch c where c.delStatus != ?1  and c.merch.id=?2 ")
				.setParameter(1, (short) 1).setParameter(2, data.getId()).getResultList();
		flag += resultList.size();
		return flag;
	}

	/**
	 * 获取ServiceFinishLevel
	 */
	public ServiceFinishLevel getFinishLevelByNameFilterId(ServiceFinishLevel data) {
		StringBuilder query = new StringBuilder(
				"select c from ServiceFinishLevel c where c.name = ?1 and c.delStatus != ?2  and c.id != ?3 and c.tenant.id = ?4 and c.item.id = ?5 ");
		List dataList = this.em.createQuery(query.toString()).setParameter(1, data.getName())
				.setParameter(2, (short) 1).setParameter(3, data.getId())
				.setParameter(4, ActionContextHolder.getContext().getTenantId())
				.setParameter(5, data.getItem().getId()).getResultList();
		ServiceFinishLevel nm = null;
		if (dataList.size() > 0) {
			nm = (ServiceFinishLevel) dataList.get(0);
		}
		return nm;
	}

	/**
	 * 获取ServiceFinishLevel
	 */
	public ServiceFinishLevel getFinishLevelByName(ServiceFinishLevel data) {
		StringBuilder query = new StringBuilder(
				"select c from ServiceFinishLevel c where c.name = ?1 and c.delStatus != ?2  and c.tenant.id = ?4 and c.item.id = ?5 ");
		List dataList = this.em.createQuery(query.toString()).setParameter(1, data.getName())
				.setParameter(2, (short) 1)
				.setParameter(4, ActionContextHolder.getContext().getTenantId())
				.setParameter(5, data.getItem().getId()).getResultList();
		ServiceFinishLevel nm = null;
		if (dataList.size() > 0) {
			nm = (ServiceFinishLevel) dataList.get(0);
		}
		return nm;
	}

	/**
	 * 验证服务项完成情况关联关系
	 */
	public int checkFinishLevelRelations(ServiceFinishLevel data) {
		int flag = 0;
		List resultList = new ArrayList<>();
		resultList = this.em
				.createQuery(
						" select c from NursingProjectServiceItem c where c.delStatus != ?1  and c.item.id = ?2 and c.tenant.id = ?3 ")
				.setParameter(1, (short) 1).setParameter(2, data.getItem().getId())
				.setParameter(3, ActionContextHolder.getContext().getTenantId()).getResultList();
		List resultLevelList = new ArrayList<>();
		resultLevelList = this.em
				.createQuery(
						" select c from NursingLevelServiceItem c where c.delStatus != ?1  and c.item.id = ?2 and c.tenant.id = ?3 ")
				.setParameter(1, (short) 1).setParameter(2, data.getItem().getId())
				.setParameter(3, ActionContextHolder.getContext().getTenantId()).getResultList();
		flag += resultList.size() + resultLevelList.size();
		return flag;
	}

	/**
	 * 验证医疗物品相应服务项的关联关系
	 */
	public int checkServiceMerchRelations(ServiceMerch data) {
		int flag = 0;
		List resultList = new ArrayList<>();
		resultList = this.em
				.createQuery(
						" select c from NursingProjectServiceItem c where c.delStatus != ?1  and c.item.id = ?2 and c.tenant.id = ?3 ")
				.setParameter(1, (short) 1).setParameter(2, data.getItem().getId())
				.setParameter(3, ActionContextHolder.getContext().getTenantId()).getResultList();
		List resultLevelList = new ArrayList<>();
		resultLevelList = this.em
				.createQuery(
						" select c from NursingLevelServiceItem c where c.delStatus != ?1  and c.item.id = ?2 and c.tenant.id = ?3 ")
				.setParameter(1, (short) 1).setParameter(2, data.getItem().getId())
				.setParameter(3, ActionContextHolder.getContext().getTenantId()).getResultList();
		flag += resultList.size() + resultLevelList.size();
		return flag;
	}

	/**
	 * 新增执行情况，如为增值服务生成增值服务账单
	 */
	@Transactional
	public void addPlanExe(NursingPlanExecute exe) {
		CustomerServiceItem item = null;
		Customer customer = null;
		if (exe.getItemProject() != null) {
			item = exe.getItemProject().getItem();
			customer = exe.getItemProject().getProject().getCustomer();
		} else if (exe.getDetail() != null && exe.getDetail().getItem().getItem() != null) {
			item = exe.getDetail().getItem().getItem();
			customer = exe.getDetail().getCustomer();
		}
		exe.setRecorder(customer);
		// 按照人数以及客户服务等级统计服务数量
		Integer curTime = 0;// 当天时间
		Integer endTime = 0;
		try {
			curTime = CommonUtil.strToIntegerTime(CommonUtil.getCurrTimeForString()
					.substring(0, 10) + " 00:00:00");// 当天时间
			endTime = CommonUtil.strToIntegerTime(CommonUtil.getCurrTimeForString()
					.substring(0, 10) + " 23:59:59");// 当天时间
		} catch (Exception e) {
			logger.error("stat one Exception " + e);
		}
		// 验证此人今天是否服务过
		List<Long> customerIdsService = new ArrayList<>();
		customerIdsService = this.em
				.createQuery(
						"select a.recorder.id from NursingPlanExecute a where a.delStatus != ?1 and a.exeStaff.id =?2"
								+ "  and a.createDateTime>=?3 and a.createDateTime<=?4 ")
				.setParameter(1, (short) 1).setParameter(2, exe.getExeStaff().getId())
				.setParameter(3, curTime).setParameter(4, endTime).getResultList();
		List<Long> customerIdsDrug = new ArrayList<>();
		customerIdsDrug = this.em
				.createQuery(
						"select b.customerDrug.customer.id from CustomerDrugProjectExe b where  b.delStatus != ?1"
								+ " and b.createDateTime>=?3 and b.createDateTime<=?4 and b.lastUpdateUser.id in (select c.id from User c where c.employee.id=?2)")
				.setParameter(1, (short) 1).setParameter(2, exe.getExeStaff().getId())
				.setParameter(3, curTime).setParameter(4, endTime).getResultList();
		customerIdsService.addAll(customerIdsDrug);
		// 执行信息存储
		dslJpaService.setEntityClass(NursingPlanExecute.class);
		if (exe.getId() == null) {
			dslJpaService.create(exe);
			try {
				String hour = exe.getPlanExeDate();
				if(!hour.equals("")) {
					String dataTime = CommonUtil.getCurrTimeForString();
					// 超时时间
					Integer nursingOvertime = commonService.getConfByCode("nursingOvertime");
					// 超前时间
					Integer nursingAdvancetime = commonService.getConfByCode("nursingAdvancetime");
					// 检查服务计划是否超时或者超前
					String timeString = dataTime.substring(0, 10) + " "
							+ (Integer.valueOf(hour) >= 10 ? hour : "0" + hour) + ":00:00";
					long start = plusTimeLong(timeString, -nursingAdvancetime);
					long end = plusTimeLong(timeString, nursingOvertime);
					long parseLongTime = parseLongTime(dataTime);
					String typecode = "violat1";
					Dicttype dicttype = commonService.getDicttype(typecode);
					// 超前
					if(parseLongTime < start) {
						RecordViolation recordViolation = new RecordViolation();
						recordViolation.setCreateTime(CommonUtil.getCurrTimes());
						recordViolation.setCreateDate(dataTime.substring(0, 10));
						recordViolation.setCustomer(exe.getRecorder());
						recordViolation.setEmployee(exe.getExeStaff());
						recordViolation.setSetTime(hour);
						recordViolation.setExeTime(CommonUtil.getCurrTimes());
						recordViolation.setNursingPlanDetail(exe.getDetail());
						recordViolation.setTenant(exe.getTenant());
						recordViolation.setDelStatus((short) 0);
						recordViolation.setType(dicttype);
						recordViolation.setStatus("1");
						recordViolation.setRemark("");
						dslJpaService.setEntityClass(RecordViolation.class);
						dslJpaService.create(recordViolation);
					} else if(parseLongTime >= end) { // 超时
						String currentDate = CommonUtil.getCurrTimeForString().substring(0, 10);
						String sql2 = "select c from RecordViolation c where c.delStatus != 1 "
								+ "and c.tenant.id = ?1 and c.createDate = ?2 and c.type.typecode = ?3 and c.setTime = ?4 "
								+ "and c.nursingPlanDetail is not null and c.nursingPlanDetail = ?5 ";
						List<RecordViolation> list = this.em.createQuery(sql2).setParameter(1, exe.getTenant().getId())
								.setParameter(2, currentDate).setParameter(3, typecode).setParameter(4, hour)
								.setParameter(5, exe.getDetail()).getResultList();
						if(list.size() > 0) {
							RecordViolation recordViolation = list.get(0);
							recordViolation.setStatus("3");
							recordViolation.setExeTime(CommonUtil.getCurrTimes());
							recordViolation.setEmployee(exe.getExeStaff());
							dslJpaService.setEntityClass(RecordViolation.class);
							dslJpaService.update(recordViolation);
						} else {
							RecordViolation recordViolation = new RecordViolation();
							recordViolation.setCreateTime(CommonUtil.getCurrTimes());
							recordViolation.setCreateDate(dataTime.substring(0, 10));
							recordViolation.setCustomer(exe.getRecorder());
							recordViolation.setEmployee(exe.getExeStaff());
							recordViolation.setSetTime(hour);
							recordViolation.setExeTime(CommonUtil.getCurrTimes());
							recordViolation.setNursingPlanDetail(exe.getDetail());
							recordViolation.setTenant(exe.getTenant());
							recordViolation.setDelStatus((short) 0);
							recordViolation.setType(dicttype);
							recordViolation.setStatus("3");
							recordViolation.setRemark("");
							dslJpaService.setEntityClass(RecordViolation.class);
							dslJpaService.create(recordViolation);
						}
					}
				}
			} catch(Exception e) {
				logger.error("添加服务计划违规记录出错", e);
			}
		} else {
			dslJpaService.update(exe);
		}

		// 处理关联的手环预警信息
		if (exe.getWarning() != null) {
			dslJpaService.setEntityClass(HbeaconWarning.class);
			exe.getWarning().setFlag(
					commonService.getDicttype(CommonConstants.DICTTYPE.BUTTON_STATUS_3.label()));// 已处理
			exe.getWarning().setOperateTime(CommonUtil.getCurrTimes());
			exe.getWarning().setOperater(exe.getExeStaff());
			dslJpaService.update(exe.getWarning());
		}
		// 服务为增值服务生成增值服务账单
		if (item != null
				&& item.getServiceValueType() != null
				&& CommonConstants.DICTTYPE.SERVICEVALUETYPE_ZZ.label().equals(
						item.getServiceValueType().getTypecode())) {
			String dayTime = CommonUtil.getCurrTimeForString();
			String year = dayTime.substring(0, 4);
			String month = dayTime.substring(5, 7);
			String remark = "";
			Double total = 0.0;
			// 服务对应的消耗品
			List<ServiceMerch> merchList = new ArrayList<>();
			merchList = this.em
					.createQuery(
							" select c from ServiceMerch c where c.delStatus != ?1  and c.item.id = ?2 ")
					.setParameter(1, (short) 1).setParameter(2, item.getId()).getResultList();
			remark += "医疗用品消耗:";
			for (ServiceMerch sm : merchList) {
				int mNum = 0;
				Double nPrice = 0.0;
				if (sm != null && sm.getMerchNum() != null && sm.getMerch() != null
						&& sm.getMerch().getPrice() != null) {
					mNum = sm.getMerchNum();
					nPrice = sm.getMerch().getPrice();
					total += mNum * nPrice;
					remark += " " + sm.getMerch().getName() + " 数量:" + sm.getMerchNum() + " 单价:"
							+ nPrice + "元;";
				}
			}
			CustomerServiceBill bill = new CustomerServiceBill();
			bill.setCustomer(customer);
			bill.setBillYear(Integer.parseInt(year));
			bill.setBillMonth(Integer.parseInt(month));
			bill.setBillTime(CommonUtil.getCurrTimes());
			bill.setTenant(customer.getTenant());
			bill.setBillStatus(commonService
					.getDicttype(CommonConstants.DICTTYPE.DAY_BILL_STATUS_WJS.label()));
			Double servicePrice = 0.0;
			if (item.getPrice() == null) {

			} else {
				servicePrice = Double.parseDouble(item.getPrice());
			}
			total += servicePrice;
			remark += "/n增值服务费用:" + item.getName() + " 价格:" + servicePrice + "元;";
			bill.setRemark(remark);
			bill.setTotal(total);
			bill.setExe(exe);
			dslJpaService.setEntityClass(CustomerServiceBill.class);
			dslJpaService.create(bill);
		}
		statService.createServiceExeStat(customer, exe.getExeStaff(), curTime, endTime,
				customerIdsService);
	}

	/**
	 * 护理计划是否执行过
	 */
	public int checkPlanDetailExeRelations(NursingPlanDetail data) {
		StringBuilder queryNow = new StringBuilder(
				"select c from  NursingPlanExecute c where c.delStatus!=1 and c.detail is not null  "
						+ " and c.detail.id =?1  ");
		List dataList = this.em.createQuery(queryNow.toString()).setParameter(1, data.getId())
				.getResultList();
		if (dataList == null || dataList.size() == 0) {
			return 0;
		} else
			return dataList.size();
	}

	/**
	 * @author huibati 创建用药计划执行并修改老人剩余药量 2017年6月30日
	 */
	@Transactional
	public CustomerDrugProjectExe operateCustomerDrugProjectExe(CustomerDrugProjectExe exe) {
		if (exe.getId() == null) {
			// 验证是否执行过
			try {
				String curTime = CommonUtil.getCurrTimeForString();// 当日日期
				Integer curTimeStart = CommonUtil.strToIntegerTime(curTime.substring(0, 10)
						+ " 00:00:00");
				Integer curTimeEnd = CommonUtil.strToIntegerTime(curTime.substring(0, 10)
						+ " 23:59:59");
				List<CustomerDrugProjectExe> exes = this.em
						.createQuery(
								" select c from CustomerDrugProjectExe c where c.delStatus != ?1  and c.drugProject.id = ?2 and c.useDrugDate = ?3 and c.createDateTime>= ?4 and c.createDateTime<= ?5")
						.setParameter(1, (short) 1).setParameter(2, exe.getDrugProject().getId())
						.setParameter(3, exe.getUseDrugDate()).setParameter(4, curTimeStart)
						.setParameter(5, curTimeEnd).getResultList();
				if (exes != null && exes.size() > 0) {
					exe.setErrcode(15);
					return exe;
				}
			} catch (ParseException e1) {
				logger.error(e1);
			}
			// 按照人数以及客户服务等级统计服务数量
			Integer curTime = 0;// 当天时间
			Integer endTime = 0;
			try {
				curTime = CommonUtil.strToIntegerTime(CommonUtil.getCurrTimeForString().substring(
						0, 10)
						+ " 00:00:00");// 当天时间
				endTime = CommonUtil.strToIntegerTime(CommonUtil.getCurrTimeForString().substring(
						0, 10)
						+ " 23:59:59");// 当天时间
			} catch (Exception e) {
				logger.error("stat one Exception " + e);
			}
			// 验证此人今天是否服务过
			List<Long> customerIdsService = new ArrayList<>();
			customerIdsService = this.em
					.createQuery(
							"select a.recorder.id from NursingPlanExecute a where a.delStatus != ?1 and a.exeStaff.id =?2"
									+ "  and a.createDateTime>=?3 and a.createDateTime<=?4 ")
					.setParameter(1, (short) 1)
					.setParameter(2, exe.getLastUpdateUser().getEmployee().getId())
					.setParameter(3, curTime).setParameter(4, endTime).getResultList();
			List<Long> customerIdsDrug = new ArrayList<>();
			customerIdsDrug = this.em
					.createQuery(
							"select b.customerDrug.customer.id from CustomerDrugProjectExe b where  b.delStatus != ?1"
									+ " and b.createDateTime>=?3 and b.createDateTime<=?4 and b.lastUpdateUser.id in (select c.id from User c where c.employee.id=?2)")
					.setParameter(1, (short) 1)
					.setParameter(2, exe.getLastUpdateUser().getEmployee().getId())
					.setParameter(3, curTime).setParameter(4, endTime).getResultList();
			customerIdsService.addAll(customerIdsDrug);
			// 更改用药量
			Long customerDrugId = exe.getCustomerDrug().getId();
			dslJpaService.setEntityClass(CustomerDrug.class);
			// 每次获取老人药品数量时都需要查询最新的
			CustomerDrug customerDrug = (CustomerDrug) dslJpaService.findById(customerDrugId);
			if (customerDrug.getDrugNum() - exe.getDrugNum() < 0) {
				exe.setErrcode(14);
				return exe;
			}
			customerDrug.setDrugNum(customerDrug.getDrugNum() - exe.getDrugNum());
			customerDrug.setLastUpdateDateTime(CommonUtil.getCurrTimes());
			dslJpaService.setEntityClass(CustomerDrug.class);
			dslJpaService.update(customerDrug);
			// 创建用药计划执行
			if (exe.getExeDate() == null) {
				exe.setExeDate(CommonUtil.getCurrTimes());
			}
			dslJpaService.setEntityClass(CustomerDrugProjectExe.class);
			dslJpaService.create(exe);
			try {
				String dataTime = CommonUtil.getCurrTimeForString();
				// 超时时间
				Integer drugOvertime = commonService.getConfByCode("drugOvertime");
				// 超前时间
				Integer drugAdvancetime = commonService.getConfByCode("drugAdvancetime");
				// 检查用药计划是否超时或者超前
				String hour = exe.getUseDrugDate();
				String timeString = dataTime.substring(0, 10) + " "
						+ (Integer.valueOf(hour) >= 10 ? hour : "0" + hour) + ":00:00";
				long start = plusTimeLong(timeString, -drugAdvancetime);
				long end = plusTimeLong(timeString, drugOvertime);
				
				long parseLongTime = parseLongTime(dataTime);
				String typecode = "violat2";
				Dicttype dicttype = commonService.getDicttype(typecode);
				// 超前
				logger.info("手动执行用药计划 " + (parseLongTime > end) + "  timeString " + timeString + "  dataTime " + dataTime);
				if(parseLongTime < start) {
					RecordViolation recordViolation = new RecordViolation();
					recordViolation.setCreateTime(CommonUtil.getCurrTimes());
					recordViolation.setCreateDate(dataTime.substring(0, 10));
					recordViolation.setCustomer(exe.getCustomerDrug().getCustomer());
					recordViolation.setEmployee(exe.getLastUpdateUser().getEmployee());
					recordViolation.setSetTime(hour);
					recordViolation.setExeTime(CommonUtil.getCurrTimes());
					recordViolation.setCustomerDrugProject(exe.getDrugProject());;
					recordViolation.setTenant(exe.getTenant());
					recordViolation.setDelStatus((short) 0);
					recordViolation.setType(dicttype);
					recordViolation.setStatus("1");
					recordViolation.setRemark("");
					dslJpaService.setEntityClass(RecordViolation.class);
					dslJpaService.create(recordViolation);
				} else if(parseLongTime > end) { // 超时
					String currentDate = CommonUtil.getCurrTimeForString().substring(0, 10);
					String sql2 = "select c from RecordViolation c where c.delStatus != 1 "
							+ "and c.tenant.id = ?1 and c.createDate = ?2 "
							+ "and c.type.typecode = ?3 and c.setTime = ?4 "
							+ "and c.customer.id = ?5 and c.customerDrugProject is not null and c.customerDrugProject = ?6";
					List<RecordViolation> list = this.em.createQuery(sql2).setParameter(1, exe.getTenant().getId())
					.setParameter(2, currentDate).setParameter(3, typecode)
					.setParameter(4, hour).setParameter(5, exe.getCustomerDrug().getCustomer().getId())
					.setParameter(6, exe.getDrugProject()).getResultList();
					if(list.size() > 0) {
						RecordViolation recordViolation = list.get(0);
						recordViolation.setStatus("3");
						recordViolation.setEmployee(exe.getLastUpdateUser().getEmployee());
						recordViolation.setExeTime(CommonUtil.getCurrTimes());
						dslJpaService.setEntityClass(RecordViolation.class);
						dslJpaService.update(recordViolation);
					} else {
						RecordViolation recordViolation = new RecordViolation();
						recordViolation.setCreateTime(CommonUtil.getCurrTimes());
						recordViolation.setCreateDate(dataTime.substring(0, 10));
						recordViolation.setCustomer(exe.getCustomerDrug().getCustomer());
						recordViolation.setEmployee(exe.getLastUpdateUser().getEmployee());
						recordViolation.setSetTime(hour);
						recordViolation.setExeTime(CommonUtil.getCurrTimes());
						recordViolation.setCustomerDrugProject(exe.getDrugProject());;
						recordViolation.setTenant(exe.getTenant());
						recordViolation.setDelStatus((short) 0);
						recordViolation.setType(dicttype);
						recordViolation.setStatus("3");
						recordViolation.setRemark("");
						dslJpaService.setEntityClass(RecordViolation.class);
						dslJpaService.create(recordViolation);
					}
				}
			} catch(Exception e) {
				logger.error("添加用药计划违规记录出错", e);
			}

			// 生成库存记录
			CustomerDrugRecord record = new CustomerDrugRecord();
			record.setCustomerDrug(customerDrug);
			record.setAddDrugNum(exe.getDrugNum());
			record.setAddType(commonService.getDicttype(CommonConstants.DICTTYPE.ADD_DRUG_TYPE_OUT
					.label()));
			record.setDrugNum(customerDrug.getDrugNum());
			if (exe.getLastUpdateUser() != null) {
				record.setGatherStaff(exe.getLastUpdateUser().getName());
			}
			record.setCreateDateTime(CommonUtil.getCurrTimes());
			dslJpaService.setEntityClass(CustomerDrugRecord.class);
			dslJpaService.create(record);
			// 判断是否发起药量不足提醒
			int msgFlag = 0;// checkDrugNum(customerDrug);
			if (msgFlag == 1) {
				// 关注此老人的
				List<User> users = this.em
						.createQuery(
								" select c.staff from StaffCustomer c where c.delStatus != ?1  and c.customer.id = ?2 ")
						.setParameter(1, (short) 1)
						.setParameter(2, customerDrug.getCustomer().getId()).getResultList();
				if (users != null && users.size() > 0) {
					for (User user : users) {
						String openId = user.getOpenId();
						if (openId != null && !"".equals(openId)) {
							String templateID = properties.getProperty("weixin.drug_templateId");
							HashMap<String, String> tempData = new HashMap<String, String>();
							tempData.put("first", customerDrug.getDrug().getName());
							tempData.put("keyword1", customerDrug.getDrugNum().toString());// 剩余量
							tempData.put("keyword2", CommonUtil.getCurrTimeForString());// 时间
							// tempData.put("keyword3", "");
							tempData.put("remark", "用药人:" + customerDrug.getCustomer().getName());
							try {
								weiXinService.send_template_message(openId, tempData, "",
										templateID);
							} catch (Exception e) {
								logger.error("weixin send template msg error:" + e);
							}
						}
					} // end for user
				}
			} // end if msgFlag
				// 按照人数以及客户服务等级统计服务数量
			statService.createServiceExeStat(exe.getCustomerDrug().getCustomer(), exe
					.getLastUpdateUser().getEmployee(), curTime, endTime, customerIdsService);
		} else {
			dslJpaService.setEntityClass(CustomerDrugProjectExe.class);
			dslJpaService.update(exe);
		}
		return exe;
	}

	/**
	 * 添加时间
	 * @param startTime 带毫秒的时间格式--yyyy-MM-dd HH:mm:ss
	 * @param minute 整数，添加时间
	 * @return
	 * @throws Exception
	 */
	public static String plusTime(String startTime, int minute) throws Exception {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Date date = new Date(parseLongTime(startTime) + (minute * 60 * 1000));
		return sdf.format(date);
	}
	public static long plusTimeLong(String startTime, int minute) throws Exception {
		return parseLongTime(startTime) + (minute * 60 * 1000);
	}

	/**
	 * 将时间转换成毫秒 参数格式-- yyyy-MM-dd HH:mm:ss.S
	 * @param time
	 * @return
	 * @throws Exception
	 */
	public static long parseLongTime(String time) throws Exception {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Date date = sdf.parse(time);
		return date.getTime();
	}
	/**
	 * 验证剩余药量是否足够 drugNum 客户剩余药量
	 */
	public int checkDrugNum(CustomerDrug cd) {
		Double drugUsePlan = 0.0;// 计划未来10天用药量
		Double dayNum = Double.valueOf(properties.getProperty("drug.day_num"));
		StringBuilder queryNow = new StringBuilder(
				"select c from CustomerDrugProject c where c.delStatus!=1 and c.customerDrug.id=?1 ");
		List dataList = this.em.createQuery(queryNow.toString()).setParameter(1, cd.getId())
				.getResultList();
		if (dataList == null || dataList.size() == 0) {
			return 0;
		} else {
			drugUsePlan = ((CustomerDrugProject) dataList.get(0)).getUseDrugNum()
					* ((CustomerDrugProject) dataList.get(0)).getUseDrugFreq() * 10;
		}
		if (cd.getDrugNum() >= drugUsePlan) {
			return 0;// 充足
		} else {
			return 1;// 不足
		}
	}

	/**
	 * 获取老人对应的护理组Staff
	 */
	public List<Employee> getEmployeeByCID(long customerId) {
		StringBuilder queryEmployee = new StringBuilder(
				" select en.employee from EmployeeNursingGroup en where en.delStatus != 1 and en.group in "
						+ " ( select bn.group from BedNurseGroup bn where bn.delStatus != 1 and bn.bed in (select c.bed from Customer c where c.delStatus != 1 and c.id=?1) ) ");
		List<Employee> staffList = this.em.createQuery(queryEmployee.toString())
				.setParameter(1, customerId).getResultList();
		return staffList;
	}

	/**
	 * 获取时间点之后的老人plandetail对应的projectitem
	 */
	public List<NursingProjectServiceItem> getProjectItemFromPlanDetail(long customerId,
			int dateTime) {
		Date now = new Date(dateTime * 1000l);
		Integer weekIndex = CommonUtil.getWeekIndexFromSun(now);
		Integer yearTab = now.getYear() + 1900;
		Integer weekTab = CommonUtil.getWeek(now);
		if (weekTab == 0) {
			weekTab = 7;
		}
		/*
		 * StringBuilder query = new StringBuilder(
		 * "select distinct c.item from NursingPlanDetail c where c.delStatus != ?1 and c.item is not null and c.customer.id=?2"
		 * + " and (" +
		 * "  ( c.yearTab<?3 ) or ( c.yearTab=?3 and c.weekIndex < ?4  ) or ( c.yearTab=?3 and c.weekIndex = ?4 and c.weekTab <=?5 ) "
		 * + " )"); List<NursingProjectServiceItem> dataList =
		 * this.em.createQuery(query.toString()) .setParameter(1, (short)
		 * 1).setParameter(2, customerId).setParameter(3, yearTab)
		 * .setParameter(4, weekIndex).setParameter(5, weekTab).getResultList();
		 */
		StringBuilder query = new StringBuilder(
				"select distinct c.item from NursingPlanServiceItem c where c.delStatus != ?1 and c.item is not null and c.customer.id=?2");
		List<NursingProjectServiceItem> dataList = this.em.createQuery(query.toString())
				.setParameter(1, (short) 1).setParameter(2, customerId).getResultList();
		return dataList;
	}

	/**
	 * @author huibati 删除任务执行情况planexe同时删除相应增值服务账单 2017年7月19日
	 */
	@Transactional
	public void deleteNursingPlanExecute(NursingPlanExecute exe) {
		StringBuilder deleteExe = new StringBuilder(
				"update  NursingPlanExecute rp set rp.delStatus=1 where rp.id = ?1  ");
		this.em.createQuery(deleteExe.toString()).setParameter(1, exe.getId()).executeUpdate();
		StringBuilder deleteServiceBill = new StringBuilder(
				"update  CustomerServiceBill rp set rp.delStatus=1 where rp.exe.id = ?1 ");
		this.em.createQuery(deleteServiceBill.toString()).setParameter(1, exe.getId())
				.executeUpdate();
	}

	/**
	 * 获取老人每天需要的护理服务和用药计划总数
	 *
	 * @author ytche
	 * @param customerList
	 * @param positonType
	 * @param itemType
	 * @return
	 * @date 2017年8月23日 下午6:17:16
	 */
	public int getDayServiceNum(List<Customer> customerList) {
		// 生活照护类服务
		final String itemType = "serviceType2";

		List<Long> customerIdList = Lists.newArrayList();
		for (Customer customer : customerList) {
			customerIdList.add(customer.getId());
		}
		List<NursingPlanDetail> detailList = getPlanDetailByCustomer(customerIdList, null, itemType);
		Integer nursingPlanNum = detailList == null ? 0 : detailList.size();
		List<CustomerDrugProject> projectList = getDrugProjectByCustomer(customerIdList, null,
				itemType);
		Integer drugProjectNum = 0;
		for (CustomerDrugProject customerDrugProject : projectList) {
			String[] timeArray = customerDrugProject.getUseDrugDate().split(",");
			drugProjectNum += timeArray.length;
		}
		return nursingPlanNum + drugProjectNum;
	}

	/**
	 * 产生护理项目标签随机产生remark
	 *
	 * @author huibati
	 * @param 2017年9月9日
	 */
	public ServiceFinishLevel createServiceFinishLevel(ServiceFinishLevel data) {
		StringBuilder query = new StringBuilder(
				" select en from ServiceFinishLevel en where en.delStatus != 1 and en.item.id =?1 and en.remark = ?2 ");
		String code = "";
		while (true) {
			code = "c" + CommonUtil.buildRandom(8);
			List<ServiceFinishLevel> dataList = this.em.createQuery(query.toString())
					.setParameter(1, data.getItem().getId()).setParameter(2, code).getResultList();
			if (dataList == null || dataList.size() == 0) {
				data.setRemark(code);
				break;
			}
		}
		dslJpaService.setEntityClass(ServiceFinishLevel.class);
		dslJpaService.create(data);
		return data;
	}

	/**
	 * 产生用药以及护理计划执行记录
	 */
	public List<ServicesExe> getServicesExe(Integer startTime, Integer endTime, Long customerId) {
		StringBuilder queryLevel = new StringBuilder(
				"select  c  from ServiceFinishLevel c where delStatus=0 and (tenant.id= :tenantId or remark like 'default%' )");
		List<ServiceFinishLevel> levels = this.em.createQuery(queryLevel.toString())
				.setParameter("tenantId", ActionContextHolder.getContext().getTenantId())
				.getResultList();
		Map<String, String> levelMap = levels.stream().collect(
				Collectors.toMap(ServiceFinishLevel::getRemark, ServiceFinishLevel::getName, (key1,
						key2) -> key2));

		long idTemp = 8;
		List<ServicesExe> dataList = new ArrayList<>();
		StringBuilder queryStr = new StringBuilder(
				"select  c,c3 from CustomerDrugProjectExe c, Conf c3 where c.delStatus=0 and c.tenant.id= :tenantId "
						+ " and c.createDateTime >= :startTime "
						+ " and c.createDateTime <:endTime "
						+ " and c.customerDrug.customer.id = :customerId"
						+ " and c3.code='drugDay' " + " order by c.createDateTime ");
		List drugProjectExes = this.em.createQuery(queryStr.toString())
				.setParameter("tenantId", ActionContextHolder.getContext().getTenantId())
				.setParameter("startTime", startTime).setParameter("endTime", endTime)
				.setParameter("customerId", customerId).getResultList();
		if (drugProjectExes != null) {
			Iterator it = drugProjectExes.iterator();
			while (it.hasNext()) {
				Object[] res = (Object[]) it.next();
				double useDrugNum = ((CustomerDrugProjectExe) res[0]).getDrugProject()
						.getUseDrugNum();
				double useDrugFreq = ((CustomerDrugProjectExe) res[0]).getDrugProject()
						.getUseDrugFreq();
				double drugNum = ((CustomerDrugProjectExe) res[0]).getDrugProject()
						.getCustomerDrug().getDrugNum();
				Conf fConf = ((Conf) res[1]);
				double dayNum = Double.parseDouble(fConf.getValue());
				if (drugNum <= dayNum * useDrugFreq * useDrugNum) {
					int days = 0;
					if (drugNum <= 0) {

					} else {
						days = (int) (drugNum / (useDrugFreq * useDrugNum));
					}
					((CustomerDrugProjectExe) res[0]).setRemarkAdd(days + "");
				}
				ServicesExe sexe = new ServicesExe();
				sexe.setDrugExe((CustomerDrugProjectExe) res[0]);
				sexe.setId(idTemp);
				dataList.add(sexe);
				idTemp++;
			}
			// for (CustomerDrugProjectExe exe : drugProjectExes) {
			// ServicesExe sexe = new ServicesExe();
			// sexe.setDrugExe(exe);
			// sexe.setId(idTemp);
			// dataList.add(sexe);
			// idTemp++;
			// }
		}
		StringBuilder queryStrP = new StringBuilder(
				"select  c  from NursingPlanExecute c where delStatus=0 and tenant.id= :tenantId "
						+ " and createDateTime >= :startTime " + " and createDateTime <:endTime "
						+ " and itemProject.project.customer.id = :customerId "
						+ " order by createDateTime ");
		List<NursingPlanExecute> planExes = this.em.createQuery(queryStrP.toString())
				.setParameter("tenantId", ActionContextHolder.getContext().getTenantId())
				.setParameter("startTime", startTime).setParameter("endTime", endTime)
				.setParameter("customerId", customerId).getResultList();
		if (planExes != null) {
			for (NursingPlanExecute exe : planExes) {
				if (exe.getExeTabRemark() != null && exe.getExeTabRemark().contains("remarkStr")) {
					String[] temp = exe.getExeTabRemark().replace(":", "").replace("remarkStr", "")
							.replace("{", "").replace("}", "").replace("\"", "").split(",");
					String jsonString = "";
					for (String code : temp) {
						jsonString += levelMap.get(code) + ",";
					}
					if (jsonString.length() > 0) {
						jsonString = jsonString.substring(0, jsonString.length() - 1);
					}
					exe.setExeTabRemark(jsonString);
				}
				ServicesExe sexe = new ServicesExe();
				sexe.setItemExe(exe);
				sexe.setId(idTemp);
				dataList.add(sexe);
				idTemp++;
			}
		}
		return dataList;
	}

	/**
	 * 获取与预警信息关联的执行情况信息
	 *
	 * @author huibati
	 * @param 2017年9月21日
	 */
	public String getExeRemark(HbeaconWarning warning) {
		String exeRemark = "";
		// 执行情况标签map
		StringBuilder queryLevel = new StringBuilder(
				"select  c  from ServiceFinishLevel c where delStatus=0 and (tenant.id= :tenantId or remark like 'default%' )");
		List<ServiceFinishLevel> levels = this.em.createQuery(queryLevel.toString())
				.setParameter("tenantId", ActionContextHolder.getContext().getTenantId())
				.getResultList();
		Map<String, String> levelMap = levels.stream().collect(
				Collectors.toMap(ServiceFinishLevel::getRemark, ServiceFinishLevel::getName, (key1,
						key2) -> key2));
		// 执行情况列表
		StringBuilder queryExe = new StringBuilder(
				"select  c  from NursingPlanExecute c where c.delStatus=0 and c.warning=?1 ");
		List<NursingPlanExecute> exes = this.em.createQuery(queryExe.toString())
				.setParameter(1, warning).getResultList();
		// 拼接数据信息
		if (exes != null) {
			for (NursingPlanExecute exe : exes) {
				if (exe.getItemProject() != null) {
					exeRemark += exe.getItemProject().getItem().getName();
				} else if (exe.getDetail() != null && exe.getDetail().getItem().getItem() != null) {
					exeRemark += exe.getDetail().getItem().getItem().getName();
				}
				String jsonString = "";
				if (exe.getExeTabRemark() != null && exe.getExeTabRemark().contains("remarkStr")) {
					String[] temp = exe.getExeTabRemark().replace(":", "").replace("remarkStr", "")
							.replace("{", "").replace("}", "").replace("\"", "").split(",");
					for (String code : temp) {
						jsonString += levelMap.get(code) + ",";
					}
					if (jsonString.length() > 0) {
						jsonString = jsonString.substring(0, jsonString.length() - 1);
						exeRemark += ":" + jsonString;
					}
				}
				if (exe.getRemark() != null && !"".equals(exe.getRemark())) {
					if (jsonString.length() > 0) {
						exeRemark += "," + exe.getRemark() + ";";
					} else {
						exeRemark += ":" + exe.getRemark() + ";";
					}
				} else {
					exeRemark += ";";
				}
			}
		}
		return exeRemark;
	}

	/**
	 * 产生下周用餐计划
	 *
	 * @author huibati
	 * @param dataTime
	 *            当前时间 2017年9月25日
	 */
	public void createFoodPlans(List<Customer> customers, int dataTime) {
		logger.debug("start create createFoodPlans " + CommonUtil.getCurrTimeForString());
		List dataList = new ArrayList<>();
		Date dateTemp = new Date(dataTime * 1000l);
		dateTemp = CommonUtil.getNextSaturday(dateTemp, 1);// 下周6的时间
		dataTime = (int) (dateTemp.getTime() / 1000);
		int weekIndex = CommonUtil.getWeekIndexFromSun(dateTemp);
		int year = dateTemp.getYear() + 1900;// 产生 年 周 序号
		Dicttype wsx = commonService.getDicttype(CommonConstants.DICTTYPE.FOOD_PLAN_STATUS_WSX
				.label());// 未生效
		Dicttype wqr = commonService
				.getDicttype(CommonConstants.DICTTYPE.FOOD_PLAN_CONFIRM_STATUS_WQR.label());// 未确认
		Dicttype zao = commonService.getDicttype(CommonConstants.DICTTYPE.FOOD_PLAN_STATUS_WSX
				.label());// 早餐
		Dicttype zhong = commonService.getDicttype(CommonConstants.DICTTYPE.FOOD_PLAN_STATUS_WSX
				.label());// 午餐
		Dicttype wan = commonService.getDicttype(CommonConstants.DICTTYPE.FOOD_PLAN_STATUS_WSX
				.label());// 晚餐
		// 生成用餐计划
		if (customers != null && customers.size() > 0) {
			for (int j = 0; j <= customers.size(); j++) {
				for (int i = 6; i >= 0; i--) {
					CustomerFoodPlan planZao = new CustomerFoodPlan();// 早餐
					planZao.setTenant(customers.get(j).getTenant());
					planZao.setCustomer(customers.get(j));
					planZao.setCreateDateTime(CommonUtil.getCurrTimes());
					planZao.setPlanStatus(wsx);
					planZao.setDiningDate(dataTime - (6 - i) * 24 * 60 * 60);// 时间戳
					planZao.setYearTab(year);
					planZao.setWeekIndex(weekIndex);
					planZao.setWeekTab(i);
					planZao.setConfirmStatus(wqr);
					planZao.setDiningTime(zao);
					dataList.add(planZao);
					CustomerFoodPlan planZhong = new CustomerFoodPlan();// 午餐
					BeanUtils.copyProperties(planZao, planZhong);
					planZhong.setDiningTime(zhong);
					dataList.add(planZhong);
					CustomerFoodPlan planWan = new CustomerFoodPlan();// 晚餐
					BeanUtils.copyProperties(planZao, planWan);
					planWan.setDiningTime(wan);
					dataList.add(planWan);
				}
			} // end if i
		}
		if (dataList.size() > 0) {
			commonService.batchInsert(dataList);
		}
	}

	/**
	 * 产生居家订单
	 *
	 * @author huibati
	 * @param dataTime
	 *            当前时间 2017年9月25日
	 */
	@Transactional
	public NursingPlanDetail createJujiaPlanDetail(NursingPlanDetail data) {
		NursingProjectServiceItem item = null;
		// 生成 projectitem
		StringBuilder queryStrP = new StringBuilder(
				"select  c  from NursingProjectServiceItem c where delStatus=0 "
						+ " and  c.project.customer=?1" + " and  c.item.id = ?2 ");
		List<NursingProjectServiceItem> itemList = this.em.createQuery(queryStrP.toString())
				.setParameter(1, data.getCustomer())
				.setParameter(2, Long.parseLong(data.getRemark())).getResultList();
		if (itemList != null && itemList.size() > 0) {
			item = itemList.get(0);
		} else {
			CustomerServiceItem serviceItem = getCustomerServiceItemById(Long.parseLong(data
					.getRemark()));
			if (serviceItem == null) {
				data.setErrcode(1);// 异常无法下单
				return data;
			}
			NursingProject project = this.getProjectByCustomer(data.getCustomer());
			// 生成NursingProject
			if (project == null) {
				project = new NursingProject();
				project.setDelStatus((short) 0);
				project.setTenant(data.getCustomer().getTenant());
				project.setCustomer(data.getCustomer());
				project.setName(data.getCustomer().getName() + "的护理方案");
				dslJpaService.setEntityClass(NursingProject.class);
				dslJpaService.create(project);
			}
			item = new NursingProjectServiceItem();
			item.setProject(project);
			item.setDelStatus((short) 0);
			item.setItem(serviceItem);
			item.setTenant(data.getCustomer().getTenant());
			dslJpaService.setEntityClass(NursingProjectServiceItem.class);
			dslJpaService.create(item);
		}
		data.setItem(item);
		data.setCreateDateTime(CommonUtil.getCurrTimes());
		data.setServiceStatus(commonService
				.getDicttype(CommonConstants.DICTTYPE.JUJIA_SERVICE_STATUS_1.label()));// 待分配
		data.setDelStatus((short) 0);
		data.setTenant(data.getCustomer().getTenant());
		data.setRemark("");
		dslJpaService.setEntityClass(NursingPlanDetail.class);
		dslJpaService.create(data);
		// 在线付款 账户扣除

		return data;
	}

	/**
	 * 取消居家订单
	 *
	 * @author huibati
	 * @param dataTime
	 *            当前时间 2017年9月25日
	 */
	@Transactional
	public NursingPlanDetail cancelJujiaPlanDetail(NursingPlanDetail data) {
		StringBuilder queryStrP = new StringBuilder(
				"select  c  from NursingPlanDetail c where  c.id = ?2 ");
		List<NursingPlanDetail> itemList = this.em.createQuery(queryStrP.toString())
				.setParameter(2, data.getId()).getResultList();
		NursingPlanDetail oldData = itemList != null && itemList.size() > 0 ? itemList.get(0)
				: null;
		if (oldData == null) {
			data.setErrcode(2);// 异常无法取消
			return data;
		} else {
			// 待定 取消条件
			if (CommonConstants.DICTTYPE.JUJIA_SERVICE_STATUS_YWC.label().equals(
					oldData.getServiceStatus().getTypecode())) {// 已完成无法取消
				data.setErrcode(3);// 订单已完成无法取消
				return data;
			}
			data.setLastUpdateDateTime(CommonUtil.getCurrTimes());
			data.setServiceStatus(commonService
					.getDicttype(CommonConstants.DICTTYPE.JUJIA_SERVICE_STATUS_1.label()));// 取消
			dslJpaService.setEntityClass(NursingPlanDetail.class);
			dslJpaService.update(data);
			// 在线付款 账户回款
			if (CommonConstants.DICTTYPE.PAY_TYPE_ZX.label().equals(
					oldData.getPaymentType().getTypecode())) {

			}
			return data;
		}

	}

	/**
	 * 获取服务项目
	 */
	public CustomerServiceItem getCustomerServiceItemById(Long id) {
		StringBuilder query = new StringBuilder(
				"select c from CustomerServiceItem c where c.id = ?1 ");
		List dataList = this.em.createQuery(query.toString()).setParameter(1, id).getResultList();
		CustomerServiceItem ct = null;
		if (dataList.size() > 0) {
			ct = (CustomerServiceItem) dataList.get(0);
		}
		return ct;
	}

	// public <S extends T> S save(final S entity) {
	// String entityClassName = entity.getClass().getName();
	// final BaseDataEntity bd = (BaseDataEntity) entity;
	// // 此三个model专门用于存放payload数据，非entity不做save操作
	// final Boolean notPayloadData =
	// !"com.lmx.repoDomain.tmodel.StaffWorkTimeSetting".equals(entityClassName)
	// &&
	// !"com.lmx.repoDomain.tmodel.CustomerNursingPlan".equals(entityClassName)
	// &&
	// !"com.lmx.repoDomain.tmodel.CustomerNursingPlanModel".equals(entityClassName)
	// && !"com.lmx.repoDomain.tmodel.HealthInfoEntry".equals(entityClassName);
	// if (notPayloadData) {
	// if (bd.getId() == null) {
	// dslJpaService.create(bd);
	// } else {
	// dslJpaService.update(bd);
	// }
	// }
	// Map<String, List<Object>> map =
	// ActionContextHolder.getContext().getPayloadDatas();
	// if (map == null || map.size() < 1) {
	// return (S) bd;
	// }
	// String pName = "";
	// try {
	// if (map.size() > 2) {
	// pName = ((String) map.get("reverse").get(0)).split(",")[0];// 获取reverse类名
	// } else {
	// pName = (String) map.get("reverse").get(0);// 获取reverse类名
	// }
	// // payload为空 删除操作将相关中间表数据删除
	// for (String key : map.keySet()) {
	// if ("reverse".equals(key)) {
	//
	// } else {
	// Class<?> clsEntity = Class.forName(entityClassName);
	// Field[] fields = clsEntity.getDeclaredFields();
	// for (Field field : fields) {
	// if (field.getName().equals(key)) {
	// System.out.println(field.getGenericType());
	// if (field.getGenericType().toString().contains("java.util.List")) {
	// String dataSimpleClassName = field.getGenericType().toString()
	// .replaceAll("java.util.List<", "").replace(">", "");
	// // String dataClassName =
	// // dataSimpleClassName.split("\\.")[4];
	// Class<?> clsData = Class.forName(dataSimpleClassName);
	// if ((map.get(key) == null || map.get(key).size() == 0)
	// && this.checkFieldExit(clsData, pName)) {
	// commonService.deleteEntity(dataSimpleClassName, pName, bd.getId(), null);
	// }
	// }
	// if (field.getGenericType().toString().contains("java.util.Set")) {
	// String dataSimpleClassName = field.getGenericType().toString()
	// .replaceAll("java.util.Set<", "").replace(">", "");
	// // String dataClassName =
	// // dataSimpleClassName.split("\\.")[4];
	// Class<?> clsData = Class.forName(dataSimpleClassName);
	// if ((map.get(key) == null || map.get(key).size() == 0)
	// && this.checkFieldExit(clsData, pName)) {
	// commonService.deleteEntity(dataSimpleClassName, pName, bd.getId(), null);
	// }
	// }
	// }
	// }
	// }
	// }
	// // payload数据不为空，保存或修改中间表数据
	// for (String key : map.keySet()) {
	// List<Object> datas = new ArrayList<>();
	// List<Object> datasTemp;
	// if ("reverse".equals(key)) {
	// logger.debug("reverse in");
	// } else {
	// datasTemp = map.get(key);
	// int deleteFlag = 0;// 用于删除list数据 标识
	// List<Long> ids = new ArrayList<>();
	// for (Object dataT : datasTemp) {
	// if (((BaseDataEntity) dataT).getId() != null) {
	// ids.add(((BaseDataEntity) dataT).getId());// 已存在的id避免删除
	// }
	// }
	// for (Object data : datasTemp) {
	// if (data != null) {
	// // 获取存取数据类名
	// String dataSimpleClassName = data.getClass().getSimpleName();
	// String dataClassName = data.getClass().getName();
	// Class<?> clsData = Class.forName(dataClassName);
	// // 护理计划如果是当周只修改或创建今天以后的数据
	// if
	// ("com.lmx.repoDomain.tmodel.CustomerNursingPlan".equals(entityClassName))
	// {// 特例护理计划
	//
	// } else {// payload 正常保存 存储前删除数据并新建或者修改数据
	// if (notPayloadData) {
	// // 增加多对一关联,多加了一个判断,一的一端可能没有多的一端的实体,需要判断一下field有无ytche
	// if (deleteFlag == 0 && this.checkFieldExit(clsData, pName)) {
	// deleteFlag = 1;
	// // 删除父类先前所对应数据
	// commonService.deleteEntity(dataSimpleClassName, pName, bd.getId(), ids);
	// }
	// // 设置reverse类的值
	// if (!"com.lmx.repoDomain.tmodel.Tenant".equals(entityClassName)) {
	// // 增加多对一关联,一的一端可能没有多的一端的实体,需要判断一下field有无ytche
	// if (this.checkFieldExit(clsData, pName)) {
	// String pMethodName = "set" + pName.replaceFirst(pName.substring(0, 1),
	// pName.substring(0, 1).toUpperCase());
	// Method setPmethod = clsData.getDeclaredMethod(pMethodName,
	// Class.forName(entityClassName));
	// setPmethod.invoke(data, bd);// 调用set方法设置reverse类的值
	// }
	// } else {
	// String pMethodName = "set" + pName.replaceFirst(pName.substring(0, 1),
	// pName.substring(0, 1).toUpperCase());
	// Method setPmethod =
	// clsData.getSuperclass().getDeclaredMethod(pMethodName,
	// Class.forName(entityClassName));
	// setPmethod.invoke(data, bd);// 调用父类set方法暂仅限于设置tenant
	// }
	// }
	// // 存在id则update 否则create
	// dslJpaService.setEntityClass(clsData);
	// if (((BaseDataEntity) data).getId() == null) {
	// if (((BaseDataEntity) data).getDelStatus() == null
	// || ((BaseDataEntity) data).getDelStatus() != 1) {
	// dslJpaService.create((BaseDataEntity) data);
	// }
	// } else {
	// dslJpaService.update((BaseDataEntity) data);
	// }
	// datas.add(data);
	// }
	// }
	// }
	// // 将保存后的list datas 放入reverse类中
	// if (datas.size() > 0) {
	// Class<?> clsEntity = Class.forName(entityClassName);
	// dslJpaService.setEntityClass(clsEntity);
	// String methodName = "set"
	// + key.replaceFirst(key.substring(0, 1), key.substring(0,
	// 1).toUpperCase());
	// Method setMethod = this.findMethodWithoutParam(clsEntity, methodName);
	// if (setMethod != null) {
	// Parameter[] params = setMethod.getParameters();
	// if (params != null && params.length > 0) {
	// // 一对多关联set List;多对一关联set Entity
	// if (List.class.isAssignableFrom(params[0].getType())) {
	// setMethod.invoke(bd, datas);
	// } else {
	// setMethod.invoke(bd, datas.get(0));
	// dslJpaService.setEntityClass(entity.getClass());
	// dslJpaService.update(bd);
	// }
	// }
	// }
	// }
	// // 设置payload 外壳 id
	// // dslJpaService.setEntityClass(Class.forName(entityClassName));
	// if (!notPayloadData) { // huibati
	// bd.setId(1L);
	// }
	// }
	// }
	// } catch (Exception e) {
	// logger.error("payload save error", e);
	// }
	// return (S) bd;
	// }

	/**
	 * 根据规范产生评估批次
	 *
	 * @author huibati
	 * @param 2017年10月30日
	 */
	@Transactional
	public EvaluateBatch createEvaluateBatchOnSource(EvaluateBatch batch) {
		String modelSourceRemark = batch.getRemark();
		List<String> modelTypes = new ArrayList<>();
		StringBuilder modelSql = new StringBuilder(
				"select c from  EvaluateModel c where c.useFlag = 0 and c.delStatus!=1 and c.modelSource is not null  "
						+ " and c.modelSource.remark =?1   order by c.createDateTime  ");
		List<Long> modelIds = new ArrayList<>();
		if (modelSourceRemark.contains("ID")) {
			modelSql.delete(0, modelSql.length());
			modelSql.append("select c from  EvaluateModel c where c.useFlag = 0 and c.delStatus!=1  "
					+ "  and c.id in (:ids) order by c.createDateTime ");
			String[] ids = modelSourceRemark.replace("ID", "").split(",");
			for (String id : ids) {
				modelIds.add(Long.parseLong(id));
			}
		}
		// 新建评估批次
		batch.setRemark("");
		batch.setDoneFlag(0);
		dslJpaService.setEntityClass(EvaluateBatch.class);
		dslJpaService.create(batch);
		List<EvaluateModel> models = new ArrayList<>();
		if (modelIds.size() > 0) {
			models = this.em.createQuery(modelSql.toString()).setParameter("ids", modelIds)
					.getResultList();
		} else {
			models = this.em.createQuery(modelSql.toString()).setParameter(1, modelSourceRemark)
					.getResultList();
			// 同一type只取一个
			for (Iterator<EvaluateModel> it = models.iterator(); it.hasNext();) {
				EvaluateModel model = it.next();
				if (model.getModelType() != null
						&& !modelTypes.contains(model.getModelType().getCode())) {
					modelTypes.add(model.getModelType().getCode());
					continue;
				}
				if (model.getModelType() != null
						&& modelTypes.contains(model.getModelType().getCode())) {
					it.remove();
				}
			}

		}
		List<EvaluateResult> results = new ArrayList<>();
		// 新建相应评估结果
		Map<Long, EvaluateResult> modelResult = new HashMap<>();
		for (EvaluateModel model : models) {
			EvaluateResult result = new EvaluateResult();
			result.setCustomer(batch.getCustomer());
			result.setEvaluateBatch(batch);
			result.setModel(model);
			result.setName(model.getTitle() + "评估结果");
			result.setCreateDateTime(CommonUtil.getCurrTimes());
			result.setDelStatus((short) 0);
			result.setTenant(batch.getCustomer().getTenant());
			results.add(result);
		}
		commonService.batchInsert(results);
		for (EvaluateResult result : results) {
			modelResult.put(result.getModel().getId(), result);
		}
		// 新建评估结果答案 默认全部未选中
		StringBuilder queryAnswer = new StringBuilder(
				"select c from  EvaluateAnswer c where c.delStatus!=1 "
						+ "and c.question.model is not null and c.question.model in (:models)   ");
		List<EvaluateAnswer> answers = new ArrayList<>();
		if (modelIds.size() > 0) {
			queryAnswer.delete(0, queryAnswer.length());
			queryAnswer.append("select c from  EvaluateAnswer c where c.delStatus!=1 "
					+ "and c.question.model is not null and c.question.model.id in (:ids) ");
			answers = this.em.createQuery(queryAnswer.toString()).setParameter("ids", modelIds)
					.getResultList();
		} else {
			answers = this.em.createQuery(queryAnswer.toString()).setParameter("models", models)
					.getResultList();
		}
		List<EvaluateExamerAnswer> examAnswers = new ArrayList<>();
		for (EvaluateAnswer answer : answers) {
			EvaluateExamerAnswer examAnswer = new EvaluateExamerAnswer();
			examAnswer.setAnswer(answer);
			examAnswer.setCreateDateTime(CommonUtil.getCurrTimes());
			examAnswer.setDelStatus((short) 0);
			examAnswer.setTenant(batch.getCustomer().getTenant());
			examAnswer.setQuestion(answer.getQuestion());
			examAnswer.setResult(modelResult.get(answer.getQuestion().getModel().getId()));
			examAnswer.setSelectFlag(0);// 未选中
			examAnswers.add(examAnswer);
		}
		commonService.batchInsert(examAnswers);
		return batch;
	}

	/**
	 * 计算评估批次分数等级
	 *
	 * @author huibati
	 * @param 2017年10月30日
	 */
	@Transactional
	public EvaluateBatch createEvaluateBatchLevelData(EvaluateBatch batch, boolean updateFlag) {
		// 更新batch信息
		if (updateFlag == true) {
			dslJpaService.setEntityClass(EvaluateBatch.class);
			dslJpaService.update(batch);
		}
		String modelSource = "";
		// 评分范围
		List<EvaluateScoreScope> scoreScopes = this.em
				.createQuery(
						"select c from  EvaluateScoreScope c where c.delStatus!=1 and c.model is not null"
								+ " and ( c.tenant.id =?1 or c.actionLevel is not null) ")
				.setParameter(1, batch.getTenant().getId()).getResultList();
		Map<Long, List<EvaluateScoreScope>> scoreScopesMap = new HashMap<>();// key
																				// modelid
		for (EvaluateScoreScope scope : scoreScopes) {
			if (scoreScopesMap.containsKey(scope.getModel().getId())) {
				scoreScopesMap.get(scope.getModel().getId()).add(scope);
			} else {
				List<EvaluateScoreScope> scopes = new ArrayList<>();
				scopes.add(scope);
				scoreScopesMap.put(scope.getModel().getId(), scopes);
			}
		}
		// batch相关模版 //每样模版只有一个 huibati
		List<EvaluateModel> models = this.em
				.createQuery(
						"select c.model from  EvaluateResult c where c.delStatus!=1 and c.evaluateBatch is not null  "
								+ " and c.evaluateBatch.id =?1  ").setParameter(1, batch.getId())
				.getResultList();
		Map<Long, Integer> modelQuestionNumMapTemp = new HashMap<>();// key
																		// modelid
																		// value
																		// 答题个数
		List<Long> modelsTemp = new ArrayList<>();// 答完moban列表
		Map<Long, List<EvaluateExamerAnswer>> modelAnswersMap = new HashMap<>();// key
																				// resultid
																				// value
																				// 相应result
																				// answer
		// batch相关result
		List<EvaluateResult> results = this.em
				.createQuery(
						"select c from  EvaluateResult c where c.delStatus!=1 and c.evaluateBatch is not null  "
								+ " and c.evaluateBatch.id =?1  ").setParameter(1, batch.getId())
				.getResultList();
		if (results == null || results.size() == 0) {
			return batch;
		}
		Map<Long, Double> resultScoreMap = new HashMap<>();// key result id
		Map<Long, NursingLevel> resultLevelMap = new HashMap<>();
		// 客户所填答案
		List<EvaluateExamerAnswer> examAnswers = this.em
				.createQuery(
						"select c from  EvaluateExamerAnswer c where c.delStatus!=1 "
								+ "and c.result in (:results)").setParameter("results", results)
				.getResultList();
		// 计算分数并统计是否答案
		if (examAnswers != null && examAnswers.size() > 0) {
			for (EvaluateExamerAnswer examerAnswer : examAnswers) {
				// 拼接result answer map
				if (modelAnswersMap.containsKey(examerAnswer.getResult().getId())) {
					List<EvaluateExamerAnswer> examAnswersTemp = modelAnswersMap.get(examerAnswer
							.getResult().getId());
					examAnswersTemp.add(examerAnswer);
					modelAnswersMap.put(examerAnswer.getResult().getId(), examAnswersTemp);
				} else {
					List<EvaluateExamerAnswer> examAnswersTemp = new ArrayList<>();
					examAnswersTemp.add(examerAnswer);
					modelAnswersMap.put(examerAnswer.getResult().getId(), examAnswersTemp);
				}
				// 统计是否打完
				if (examerAnswer.getSelectFlag() == 1) {
					if (modelQuestionNumMapTemp.containsKey(examerAnswer.getQuestion().getModel()
							.getId())) {
						Integer questionNum = modelQuestionNumMapTemp.get(examerAnswer
								.getQuestion().getModel().getId());
						modelQuestionNumMapTemp.put(examerAnswer.getQuestion().getModel().getId(),
								questionNum + 1);
					} else {
						modelQuestionNumMapTemp.put(examerAnswer.getQuestion().getModel().getId(),
								1);
					}
				}
				// 统计分数
				if (examerAnswer.getSelectFlag() == 1) {
					if (resultScoreMap.containsKey(examerAnswer.getResult().getId())) {
						Double score = resultScoreMap.get(examerAnswer.getResult().getId());
						resultScoreMap.put(examerAnswer.getResult().getId(),
								score + Double.parseDouble(examerAnswer.getAnswer().getScore()));
					} else {
						resultScoreMap.put(examerAnswer.getResult().getId(),
								Double.parseDouble(examerAnswer.getAnswer().getScore()));
					}
				}
			}
		}
		// 太烂的代码 有时间改进
		for (EvaluateModel model : models) {
			modelSource = model.getModelSource() == null ? "" : model.getModelSource().getRemark();
			List<EvaluateQuestion> questions = this.em
					.createQuery(
							"select c from  EvaluateQuestion c where c.delStatus!=1 and c.model.id =?1")
					.setParameter(1, model.getId()).getResultList();
			Integer questionNum = questions == null || questions.size() == 0 ? 0 : questions.size();
			if (modelQuestionNumMapTemp.containsKey(model.getId())
					&& modelQuestionNumMapTemp.get(model.getId()) == questionNum) {
				modelsTemp.add(model.getId());
			}
		}
		for (Long id : resultScoreMap.keySet()) {
			System.out.println("idtest:" + id + " " + resultScoreMap.get(id));
		}
		// 判断model答完没打完计算level
		for (EvaluateResult result : results) {
			result.setScore(String.valueOf(resultScoreMap.get(result.getId())));
			result.setLevel(null);
			result.setActionLevel(null);
			result.setAnswers(modelAnswersMap.get(result.getId()));
			// 已答完 计算level
			if (modelsTemp.contains(result.getModel().getId())) {
				// 特例针对这个model自行计算actionLevel
				if (result.getModel() != null
						&& result.getModel().getModelType() != null
						&& "perceptionAndCommunication".equals(result.getModel().getModelType()
								.getCode())) {
					Map<String, Integer> scoreMap = new HashMap<>();
					for (EvaluateExamerAnswer eea : result.getAnswers()) {
						if (eea.getSelectFlag() == 1) {
							scoreMap.put(eea.getAnswer().getQuestion().getCode(),
									Integer.parseInt(eea.getAnswer().getScore()));
						}
					}
					if (!scoreMap.containsKey("yishishuiping") || !scoreMap.containsKey("shili")
							|| !scoreMap.containsKey("tingli")
							|| !scoreMap.containsKey("goutongjiaoliu")) {
						continue;
					}
					if (scoreMap.get("yishishuiping") == 0
							&& (scoreMap.get("shili") == 0 || scoreMap.get("shili") == 1
									|| scoreMap.get("tingli") == 0 || scoreMap.get("tingli") == 1)
							&& scoreMap.get("goutongjiaoliu") == 0) {
						result.setActionLevel(commonService.getDicttype("actionLevel1"));
					}
					if ((scoreMap.get("yishishuiping") == 0 && (scoreMap.get("shili") == 2 || scoreMap
							.get("tingli") == 2)) || scoreMap.get("goutongjiaoliu") == 1) {
						result.setActionLevel(commonService.getDicttype("actionLevel2"));
					}
					if (((scoreMap.get("yishishuiping") == 0 && (scoreMap.get("shili") == 3 || scoreMap
							.get("tingli") == 3)) || scoreMap.get("goutongjiaoliu") == 2)
							|| (scoreMap.get("yishishuiping") == 1
									&& (scoreMap.get("shili") <= 3 || scoreMap.get("tingli") <= 3) && scoreMap
									.get("goutongjiaoliu") <= 2)) {
						result.setActionLevel(commonService.getDicttype("actionLevel3"));
					}
					if ((((scoreMap.get("yishishuiping") == 0 || scoreMap.get("yishishuiping") == 1) && (scoreMap
							.get("shili") == 4 || scoreMap.get("tingli") == 4)) || scoreMap
							.get("goutongjiaoliu") == 3)
							|| (scoreMap.get("yishishuiping") == 2 || scoreMap.get("yishishuiping") == 3)) {
						result.setActionLevel(commonService.getDicttype("actionLevel4"));
					}
				} else {
					if (scoreScopesMap.get(result.getModel().getId()) == null) {

					} else {
						for (EvaluateScoreScope scope : scoreScopesMap.get(result.getModel()
								.getId())) {
							if (scope.getMaxScore() != null && scope.getMinScore() != null
									&& resultScoreMap.get(result.getId()) >= scope.getMinScore()
									&& resultScoreMap.get(result.getId()) <= scope.getMaxScore()) {
								result.setLevel(scope.getLevel());
								result.setActionLevel(scope.getActionLevel());
							}
						}
					}
				}
			}
		}
		if (updateFlag == true) {
			commonService.batchUpdate(results);
		}
		batch.setResults(results);
		if (models.size() == modelsTemp.size()) {
			batch.setDoneFlag(1);
		} else {
			batch.setDoneFlag(0);
		}
		// 如果为规范类模版问卷需对批次 level进行计算
		if (!"qita".equals(modelSource) && models.size() == modelsTemp.size()) {
			batch = createLevelDataByResult(batch);
		}
		return batch;
	}

	/**
	 * 根据EvaluateExamerAnswer 获取batch result数据
	 *
	 * @author huibati
	 * @param 2017年11月3日
	 */
	public Iterable<EvaluateExamerAnswer> getEvaluateBatchData(
			Iterable<EvaluateExamerAnswer> examerAnswers) {
		List<Long> resultIds = new ArrayList<>();
		for (EvaluateExamerAnswer data : examerAnswers) {
			if (!resultIds.contains(data.getResult().getId())) {
				resultIds.add(data.getResult().getId());
			}
		}
		if (resultIds == null || resultIds.size() == 0) {
			return examerAnswers;
		}
		// patch相关
		List<EvaluateResult> results = this.em
				.createQuery(
						"select c from  EvaluateResult c where c.delStatus!=1   "
								+ " and c.id in (:resultIds)  ")
				.setParameter("resultIds", resultIds).getResultList();
		EvaluateBatch batch = null;
		Map<Long, EvaluateResult> resultMap = new HashMap<>();
		if (results != null && results.size() > 0) {

			List<EvaluateBatch> batchs = this.em
					.createQuery(
							"select c.evaluateBatch from  EvaluateResult c where c.delStatus!=1   "
									+ " and c in (:resultIds)  ")
					.setParameter("resultIds", results).getResultList();
			batch = batchs.get(0);
			for (EvaluateResult result : results) {
				result.setAnswers(new ArrayList<>());
			}
			// 客户所填答案
			for (EvaluateExamerAnswer answer : examerAnswers) {
				for (EvaluateResult result : results) {
					if (answer.getResult().getId() == result.getId()) {
						result.getAnswers().add(answer);
						continue;
					}
				}
			}
			batch.setResults(results);
			batch = createEvaluateBatchLevelData(batch, false);
			List<EvaluateResult> resultsTemp = batch.getResults();
			resultMap = resultsTemp.stream().collect(
					Collectors.toMap(EvaluateResult::getId, Function.identity(),
							(key1, key2) -> key2));
			for (EvaluateResult result : resultMap.values()) {
				result.setEvaluateBatch(batch);
			}

			for (EvaluateExamerAnswer answer : examerAnswers) {
				answer.setResult(resultMap.get(answer.getResult().getId()));
			}
		}
		return examerAnswers;
	}

	/**
	 * 获取评估批次相关数据
	 *
	 * @author huibati
	 * @param 2017年10月30日
	 */
	public Iterable<EvaluateBatch> getEvaluateBatchDataAll(Iterable<EvaluateBatch> batchs) {

		List batchDatas = new ArrayList<>();
		try {
			batchDatas = this.em
					.createQuery(
							"select c ,d from  EvaluateExamerAnswer c ,EvaluateBatch d where d.id=c.result.evaluateBatch.id and c.delStatus!=1 "
									+ "and c.result.evaluateBatch in (:batchs) ")
					.setParameter("batchs", batchs).getResultList();
		} catch (Exception e) {
			logger.debug("getEvaluateBatchDataAll " + e);
			return batchs;
		}
		Map<Long, EvaluateBatch> batchMap = new HashMap<>();// key batchid
		Map<Long, EvaluateResult> resultMap = new HashMap<>();// key resultid
		int index = 0;
		Iterator it = batchDatas.iterator();
		while (it.hasNext()) {
			Object[] res = (Object[]) it.next();
			EvaluateExamerAnswer examerAnswer = (EvaluateExamerAnswer) res[0];
			EvaluateBatch batch = (EvaluateBatch) res[1];
			EvaluateResult result = examerAnswer.getResult();
			result.setEvaluateBatch(batch);
			batch.setTitle(result.getModel().getModelSource().getName());
			// 建立batch map
			if (batchMap.containsKey(batch.getId())) {

			} else {
				batch.setResults(new ArrayList<>());
				batchMap.put(batch.getId(), batch);
			}
			// 建立result map
			if (resultMap.containsKey(result.getId())) {

			} else {
				result.setAnswers(new ArrayList<>());
				resultMap.put(result.getId(), result);
			}
			// 拼建answers
			if (resultMap.containsKey(examerAnswer.getResult().getId())) {
				resultMap.get(examerAnswer.getResult().getId()).getAnswers().add(examerAnswer);
			}
		}

		for (EvaluateResult result : resultMap.values()) {
			if (batchMap.containsKey(result.getEvaluateBatch().getId())) {
				batchMap.get(result.getEvaluateBatch().getId()).getResults().add(result);
			}
		}
		List<EvaluateBatch> copy = new ArrayList<EvaluateBatch>();

		for (EvaluateBatch batch : batchs) {
			copy.add(batch);
		}

		for (int i = 0; i < copy.size(); i++) {
			EvaluateBatch batch = batchMap.get(copy.get(i).getId());
			batch = createEvaluateBatchLevelData(batch, false);
			copy.set(i, batch);
		}
		return copy;
	}

	/**
	 * 获取评估批次相关数据
	 *
	 * @author huibati
	 * @param 2017年10月30日
	 */
	public EvaluateBatch getEvaluateBatchData(EvaluateBatch batch) {
		// patch相关
		List<EvaluateResult> results = this.em
				.createQuery(
						"select c from  EvaluateResult c where c.delStatus!=1 and c.evaluateBatch is not null  "
								+ " and c.evaluateBatch.id =?1  ").setParameter(1, batch.getId())
				.getResultList();
		if (results != null && results.size() > 0) {
			for (EvaluateResult result : results) {
				result.setAnswers(new ArrayList<>());
			}
			// 客户所填答案
			List<EvaluateExamerAnswer> examAnswers = this.em
					.createQuery(
							"select c from  EvaluateExamerAnswer c where c.delStatus!=1 "
									+ "and c.result in (:results)")
					.setParameter("results", results).getResultList();
			for (EvaluateExamerAnswer answer : examAnswers) {
				for (EvaluateResult result : results) {
					if (answer.getResult().getId() == result.getId()) {
						result.getAnswers().add(answer);
						continue;
					}
				}
			}
		}
		batch = createEvaluateBatchLevelData(batch, false);
		return batch;
	}

	/**
	 * 根据规范规则计算level
	 *
	 * @author huibati
	 * @param 2017年10月30日
	 */
	public EvaluateBatch createLevelDataByResult(EvaluateBatch batch) {
		List<EvaluateResult> results = batch.getResults();
		Map<String, Integer> actionLevelMap = new HashMap<>();
		Map<String, Double> scoreMap = new HashMap<>();
		for (EvaluateResult result : results) {
			Integer temp = -1;
			if (result.getActionLevel() != null) {
				if ("actionLevel1".equals(result.getActionLevel().getTypecode())) {
					temp = 0;
				}
				if ("actionLevel2".equals(result.getActionLevel().getTypecode())) {
					temp = 1;
				}
				if ("actionLevel3".equals(result.getActionLevel().getTypecode())) {
					temp = 2;
				}
				if ("actionLevel4".equals(result.getActionLevel().getTypecode())) {
					temp = 3;
				}
			}
			if (result.getModel() != null && result.getModel().getModelType() != null) {
				actionLevelMap.put(result.getModel().getModelType().getCode(), temp);
			}

			String score = result.getScore() == null ? "0" : result.getScore();
			if (result.getModel() != null && result.getModel().getModelType() != null) {
				scoreMap.put(result.getModel().getModelType().getCode(),
						Double.parseDouble(result.getScore()));
			}

		}
		// dailyLiving mentality perceptionAndCommunication socialParticipation

		if (!actionLevelMap.containsKey("dailyLiving") || !actionLevelMap.containsKey("mentality")
				|| !actionLevelMap.containsKey("perceptionAndCommunication")
				|| !actionLevelMap.containsKey("socialParticipation")) {
			return batch;
		}
		// 计算actionlevel
		if (actionLevelMap.get("dailyLiving") == 0
				&& actionLevelMap.get("mentality") == 0
				&& actionLevelMap.get("perceptionAndCommunication") == 0
				&& (actionLevelMap.get("socialParticipation") == 0 || actionLevelMap
						.get("socialParticipation") == 1)) {
			batch.setActionLevel(commonService.getDicttype("actionLevel1"));
		}
		if ((actionLevelMap.get("dailyLiving") == 0 && ((actionLevelMap.get("mentality") >= 1 || actionLevelMap
				.get("perceptionAndCommunication") >= 1) || actionLevelMap
				.get("socialParticipation") == 2))
				|| (actionLevelMap.get("dailyLiving") == 1 && ((actionLevelMap.get("mentality") == 1
						|| actionLevelMap.get("perceptionAndCommunication") == 1 || actionLevelMap
						.get("socialParticipation") == 1) || (actionLevelMap.get("mentality") == 0
						|| actionLevelMap.get("perceptionAndCommunication") == 0 || actionLevelMap
						.get("socialParticipation") == 0)))) {
			batch.setActionLevel(commonService.getDicttype("actionLevel2"));
		}
		Integer oneNum = 0;
		Integer twoNum = 0;// B、C、D中有1-2项的等级为1或2
		if (actionLevelMap.get("mentality") == 1) {
			oneNum++;
		}
		if (actionLevelMap.get("perceptionAndCommunication") == 1) {
			oneNum++;
		}
		if (actionLevelMap.get("socialParticipation") == 1) {
			oneNum++;
		}
		if (actionLevelMap.get("mentality") == 2) {
			twoNum++;
		}
		if (actionLevelMap.get("perceptionAndCommunication") == 2) {
			twoNum++;
		}
		if (actionLevelMap.get("socialParticipation") == 2) {
			twoNum++;
		}
		if ((actionLevelMap.get("dailyLiving") == 1 && ((actionLevelMap.get("mentality") == 2
				&& actionLevelMap.get("perceptionAndCommunication") == 2 && actionLevelMap
				.get("socialParticipation") == 2) || (actionLevelMap.get("mentality") == 3
				|| actionLevelMap.get("perceptionAndCommunication") == 3 || actionLevelMap
				.get("socialParticipation") == 3)))
				|| ((actionLevelMap.get("dailyLiving") == 2) && ((oneNum >= 1 && oneNum <= 2) || (twoNum >= 1 && twoNum <= 2)))) {
			batch.setActionLevel(commonService.getDicttype("actionLevel3"));
		}
		if ((actionLevelMap.get("dailyLiving") == 3)
				|| (actionLevelMap.get("dailyLiving") >= 2 && actionLevelMap.get("mentality") >= 2
						&& actionLevelMap.get("perceptionAndCommunication") >= 2 && actionLevelMap
						.get("socialParticipation") >= 2)
				|| (actionLevelMap.get("dailyLiving") == 2 && (actionLevelMap.get("mentality") == 3
						|| actionLevelMap.get("perceptionAndCommunication") == 3 || actionLevelMap
						.get("socialParticipation") == 3))) {
			batch.setActionLevel(commonService.getDicttype("actionLevel4"));
		}
		// 计算护理等级
		List<NursingLevel> levels = new ArrayList<>();
		levels = this.em
				.createQuery(
						"select c from NursingLevel c where c.delStatus!=1 and c.tenant.id =?1")
				.setParameter(1, batch.getTenant().getId()).getResultList();
		Map<String, NursingLevel> levelMap = levels.stream().collect(
				Collectors.toMap(NursingLevel::getSourceCode, Function.identity(),
						(key1, key2) -> key2));
		if (actionLevelMap.get("dailyLiving") == 0
				&& actionLevelMap.get("mentality") == 0
				&& actionLevelMap.get("perceptionAndCommunication") == 0
				&& (actionLevelMap.get("socialParticipation") == 0 || actionLevelMap
						.get("socialParticipation") == 1)) {
			batch.setLevel(levelMap.get("zili"));// 自理
			return batch;
		}
		if ((actionLevelMap.get("dailyLiving") == 0)
				&& ((actionLevelMap.get("mentality") >= 1 || actionLevelMap
						.get("perceptionAndCommunication") >= 1) || (actionLevelMap
						.get("socialParticipation") == 2))) {
			batch.setLevel(levelMap.get("jiezhu1"));// 介助1
			return batch;
		}
		if ((actionLevelMap.get("dailyLiving") == 1)
				&& ((actionLevelMap.get("mentality") == 1
						|| actionLevelMap.get("perceptionAndCommunication") == 1 || actionLevelMap
						.get("socialParticipation") == 1) || (actionLevelMap.get("mentality") == 0
						|| actionLevelMap.get("perceptionAndCommunication") == 0 || actionLevelMap
						.get("socialParticipation") == 0))) {
			batch.setLevel(levelMap.get("jiezhu2"));// 介助2
			return batch;
		}
		if ((actionLevelMap.get("dailyLiving") == 1)
				&& ((actionLevelMap.get("mentality") == 2
						&& actionLevelMap.get("perceptionAndCommunication") == 2 && actionLevelMap
						.get("socialParticipation") == 2) || (actionLevelMap.get("mentality") == 3
						|| actionLevelMap.get("perceptionAndCommunication") == 3 || actionLevelMap
						.get("socialParticipation") == 3))

		) {
			batch.setLevel(levelMap.get("jiezhu3"));// 介助3
			return batch;
		}
		if ((actionLevelMap.get("dailyLiving") == 2)
				&& ((oneNum >= 1 && oneNum <= 2) || (twoNum >= 1 && twoNum <= 2))

		) {
			batch.setLevel(levelMap.get("jiehu1"));// 介护1
			return batch;
		}

		Boolean jiehu3 = (actionLevelMap.get("dailyLiving") >= 2
				&& actionLevelMap.get("mentality") >= 2
				&& actionLevelMap.get("perceptionAndCommunication") >= 2 && actionLevelMap
				.get("socialParticipation") >= 2)
				|| (actionLevelMap.get("dailyLiving") >= 2 && (actionLevelMap.get("mentality") == 3
						|| actionLevelMap.get("perceptionAndCommunication") == 3 || actionLevelMap
						.get("socialParticipation") == 3));

		if (scoreMap.get("dailyLiving") <= 40 && !jiehu3) {
			batch.setLevel(levelMap.get("jiehu2"));// 介护2
			return batch;
		}
		if ((actionLevelMap.get("dailyLiving") >= 2 && actionLevelMap.get("mentality") >= 2
				&& actionLevelMap.get("perceptionAndCommunication") >= 2 && actionLevelMap
				.get("socialParticipation") >= 2)
				|| (actionLevelMap.get("dailyLiving") >= 2 && (actionLevelMap.get("mentality") == 3
						|| actionLevelMap.get("perceptionAndCommunication") == 3 || actionLevelMap
						.get("socialParticipation") == 3))) {
			batch.setLevel(levelMap.get("jiehu3"));// 介护3
			return batch;
		}
		return batch;
	}

	/**
	 * 获取NursingLevel
	 *
	 * @author huibati
	 * @param 2017年11月9日
	 */
	// public List<NursingLevel> getTenantNursingLevel(String queryCon, String
	// typecode) {
	// List<NursingLevel> levelList = new ArrayList<>();
	// StringBuilder query = new StringBuilder();
	// if (queryCon != null && queryCon.length() > 0) {
	// query.append("select c from NursingLevel c where   c.delStatus !=1 and c.name like '%"
	// + queryCon
	// + "%'  and  ( c.tenant.id = ?1  or "
	// +
	// " c.id in ( select c.id from NursingLevel c where c.delStatus !=1 and c.tenant.id = ?1  and c.modelSource is not null and c.modelSource.id in (select t.modelSource.id from TenantEvaModelSource t where t.delStatus !=1 and t.tenant.id=?1 )  ) )  order by c.createDateTime desc");
	// levelList = this.em.createQuery(query.toString())
	// .setParameter(1, ActionContextHolder.getContext().getTenantId())
	// .getResultList();
	// } else {
	// query.append("select c from NursingLevel c where  c.delStatus !=1  and  ( c.tenant.id = ?1  or "
	// +
	// " c.id in ( select c.id from NursingLevel c where c.delStatus !=1 and c.tenant.id = ?1  and c.modelSource is not null and c.modelSource.id in (select t.modelSource.id from TenantEvaModelSource t where t.delStatus !=1 and t.tenant.id=?1 )  ) ) order by c.createDateTime desc");
	// levelList = this.em.createQuery(query.toString())
	// .setParameter(1,
	// ActionContextHolder.getContext().getTenantId()).getResultList();
	// }
	//
	// return levelList;
	// }
	public List<NursingLevel> getTenantNursingLevel(String queryCon, String typecode) {
		List<NursingLevel> levelList = new ArrayList<>();
		StringBuilder query = new StringBuilder();
		if (queryCon != null && queryCon.length() > 0) {
			query.append("select c from NursingLevel c where  c.delStatus !=1 and c.name like '%"
					+ queryCon
					+ "%'  and c.tenant.id = ?1  "
					+ " and c.modelSource is not null "
					+ " and c.modelSource.id in (select t.modelSource.id from TenantEvaModelSource t where t.delStatus !=1 and t.tenant.id=?1 ) "
					+ " order by c.createDateTime desc");
			levelList = this.em.createQuery(query.toString())
					.setParameter(1, ActionContextHolder.getContext().getTenantId())
					.getResultList();
		} else {
			query.append("select c from NursingLevel c where  c.delStatus !=1  and c.tenant.id = ?1  "
					+ " and c.modelSource is not null "
					+ " and c.modelSource.id in (select t.modelSource.id from TenantEvaModelSource t where t.delStatus !=1 and t.tenant.id=?1 ) "
					+ " order by c.createDateTime desc");
			levelList = this.em.createQuery(query.toString())
					.setParameter(1, ActionContextHolder.getContext().getTenantId())
					.getResultList();
		}

		return levelList;
	}

	/**
	 * 删除评估批次
	 *
	 * @author huibati
	 * @param 2017年10月30日
	 */
	@Transactional
	public EvaluateBatch deleteEvaluateBatch(EvaluateBatch batch) {

		StringBuilder resultSql = new StringBuilder(
				"select c.id from  EvaluateResult c where  c.delStatus!=1   "
						+ " and c.evaluateBatch.id = ?1   ");
		List<Long> results = this.em.createQuery(resultSql.toString())
				.setParameter(1, batch.getId()).getResultList();
		if (results != null && results.size() > 0) {
			StringBuilder queryT = new StringBuilder(
					"update  EvaluateExamerAnswer rp set rp.delStatus=1 where rp.result.id in (:results) and rp.delStatus=?2 ");
			this.em.createQuery(queryT.toString()).setParameter("results", results)
					.setParameter(2, (short) 0).executeUpdate();
			StringBuilder query = new StringBuilder(
					"update  EvaluateResult rp set rp.delStatus=1 where rp.evaluateBatch.id = ?1 and rp.delStatus=?2 ");
			this.em.createQuery(query.toString()).setParameter(1, batch.getId())
					.setParameter(2, (short) 0).executeUpdate();
		}
		dslJpaService.setEntityClass(EvaluateBatch.class);
		dslJpaService.update(batch);
		return batch;
	}

}
